package com.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.crmeb.core.config.MybatisPlusConfig;
import com.crmeb.core.utils.TableNameUtil;
import com.zbkj.crmeb.chant.dto.ChannelDiscountDTO;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.model.ChannelDiscountGoods;
import com.zbkj.crmeb.chant.model.ChannelMemberLevel;
import com.zbkj.crmeb.chant.request.ChannelDiscountRequest;
import com.zbkj.crmeb.chant.service.ChannelDiscountService;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.express.model.ShippingTemplates;
import com.zbkj.crmeb.express.model.ShippingTemplatesFree;
import com.zbkj.crmeb.express.model.ShippingTemplatesRegion;
import com.zbkj.crmeb.express.service.ShippingTemplatesFreeService;
import com.zbkj.crmeb.express.service.ShippingTemplatesRegionService;
import com.zbkj.crmeb.express.service.ShippingTemplatesService;
import com.zbkj.crmeb.store.dao.StoreProductDao;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.zbkj.crmeb.agent.model.Agent;
import com.zbkj.crmeb.agent.service.AgentService;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.response.PickingProductResponse;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.express.model.FirstLogisticsCost;
import com.zbkj.crmeb.express.service.FirstLogisticsCostService;
import com.zbkj.crmeb.front.response.PriceGroupResponse;
import com.zbkj.crmeb.front.vo.ProductVo;
import com.zbkj.crmeb.front.vo.RatioVo;
import com.zbkj.crmeb.member.model.MerchantMemberBenefits;
import com.zbkj.crmeb.member.model.StoreProductDiscount;
import com.zbkj.crmeb.member.service.IMerchantMemberBenefitsService;
import com.zbkj.crmeb.member.service.IStoreProductDiscountService;
import com.zbkj.crmeb.store.request.MarkupRateRequest;
import com.zbkj.crmeb.store.response.PriceResult;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.tools.model.MoneyExchange;
import com.zbkj.crmeb.tools.service.MoneyExchangeService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserAddress;
import com.zbkj.crmeb.user.model.UserMemberRecord;
import com.zbkj.crmeb.user.service.UserMemberRecordService;
import com.zbkj.crmeb.user.service.UserService;

import cn.hutool.core.util.StrUtil;

/**
 * 价格计算工具
 *
 * @author muyu.myw
 * @date 2020/9/28 11:46
 */
@Service
@Slf4j
public class PriceUtil {
    public static final String DEFAULT_EXCHANGE_RATE_EUR = "7.8";
    public static final String DEFAULT_EXCHANGE_RATE_US = "6.5";
    public static final String DEFAULT_EXCHANGE_RATE_HK = "86";
    public static final String DEFAULT_EXCHANGE_RATE_EUR_HK = "950";

    private final static List<Integer> WINE_SECOND_CATEGORY_ID_LIST = new ArrayList<Integer>();
    static {
        WINE_SECOND_CATEGORY_ID_LIST.add(8306);
        WINE_SECOND_CATEGORY_ID_LIST.add(8305);
        WINE_SECOND_CATEGORY_ID_LIST.add(8304);
        WINE_SECOND_CATEGORY_ID_LIST.add(8303);
        WINE_SECOND_CATEGORY_ID_LIST.add(8302);
        WINE_SECOND_CATEGORY_ID_LIST.add(8299);
    }

    @Autowired
    private MoneyExchangeService moneyExchangeService;
    @Autowired
    private MarkupRateService markupRateService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private FirstLogisticsCostService firstLogisticsCostService;
    @Resource
    @Lazy
    private StoreProductMerService storeProductMerService;
    @Autowired
    private ProductUtil productUtil;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private ChannelCategoryConfigService channelCategoryConfigService;
    @Autowired
    StoreProductValueMerService storeProductValueMerService;
    @Autowired
    AgentService agentService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserMemberRecordService userMemberRecordService;
    @Autowired
    private IMerchantMemberBenefitsService merchantMemberBenefitsService;
    @Autowired
    private IStoreProductDiscountService storeProductDiscountService;
    @Autowired
    private StoreProductActivityService storeProductActivityService;
    @Autowired
    private ChannelFreeShippingActivityService channelFreeShippingActivityService;
    @Autowired
    private ChannelFreeShippingActivityCityService channelFreeShippingActivityCityService;
    @Autowired
    private ChannelDiscountService channelDiscountService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private ProductConvertUtil productConvertUtil;
    @Autowired
    private ICategoryMatchService categoryMatchService;

    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;

    @Resource
    private StoreProductDao storeProductDAO;

    @Autowired
    private ShippingTemplatesService shippingTemplatesService;

    @Autowired
    private ShippingTemplatesFreeService shippingTemplatesFreeService;

    @Autowired
    private ShippingTemplatesRegionService shippingTemplatesRegionService;

    @Resource
    private CustomsRecordService customsRecordService;

    private final static ExecutorService executorService = ThreadPoolUtils.getThread();


    /**
     * 价格计算
     *
     * @param price
     * @param rate  利润浮动
     * @return
     */
    public static BigDecimal calePrice(BigDecimal price, String rate) {
        // 售价 , 在buyer的基础上下浮 1.5%
        price = price.multiply(new BigDecimal(rate)).setScale(2, RoundingMode.HALF_UP);
        // 对个位的位数进行整理,让数字更好看 , 1234向下取整未0, 567 向上取8, 9,0不变
        int lp = price.intValue() % 10;
        switch (lp) {
            case 1:
            case 2:
            case 3:
            case 4:
                price = price.subtract(new BigDecimal(lp));
                break;
            case 5:
            case 6:
            case 7:
                price = price.add(new BigDecimal(8 - lp));
        }
        return price;
    }

    /**
     * 欧元转人民币(实时汇率)
     *
     * @param price
     * @return
     */
    public PriceResult eur2Rmb(BigDecimal price) {
        // 缓存读取汇率
        Object eurRate = redisUtil.get(Constants.EXCHANGE_EUR_KEY);
        if (null == eurRate) {
            MoneyExchange moneyExchange = moneyExchangeService.getExchangeByName(Constants.EXCHANGE_EUR_NAME);
            eurRate = null == moneyExchange ? DEFAULT_EXCHANGE_RATE_EUR : moneyExchange.getBankConversionPri();
            redisUtil.set(Constants.EXCHANGE_EUR_KEY, eurRate, 2L, TimeUnit.HOURS);
        }

        BigDecimal eur2Rmb = new BigDecimal(eurRate.toString());

        return new PriceResult(price.multiply(eur2Rmb).setScale(2, RoundingMode.UP), eur2Rmb);
    }

    /**
     * 欧元转人民币(静态汇率)
     *
     * @param otPrice
     * @return
     */
    public BigDecimal eur2RmbStatic(BigDecimal otPrice, BigDecimal rate) {
        if (null == rate) {
            Object eurRate = redisUtil.get(Constants.EXCHANGE_EUR_KEY);
            if (null == eurRate) {
                MoneyExchange moneyExchange = moneyExchangeService.getExchangeByName(Constants.EXCHANGE_EUR_NAME);
                eurRate = null == moneyExchange ? DEFAULT_EXCHANGE_RATE_EUR : moneyExchange.getBankConversionPri();
                redisUtil.set(Constants.EXCHANGE_EUR_KEY, eurRate, 2L, TimeUnit.HOURS);
            }
            rate = new BigDecimal(eurRate.toString());
        }

        return otPrice.multiply(rate).setScale(2, RoundingMode.UP);
    }

    /**
     * 人民币转欧元(动态汇率)
     *
     * @param price
     * @return
     */
    public BigDecimal rmb2Eur(BigDecimal price) {
        if (price == null) {
            return BigDecimal.ZERO;
        }

        // 缓存读取汇率
        Object eurRate = redisUtil.get(Constants.EXCHANGE_EUR_KEY);
        if (null == eurRate) {
            MoneyExchange moneyExchange = moneyExchangeService.getExchangeByName(Constants.EXCHANGE_EUR_NAME);
            eurRate = null == moneyExchange ? DEFAULT_EXCHANGE_RATE_EUR : moneyExchange.getBankConversionPri();
            redisUtil.set(Constants.EXCHANGE_EUR_KEY, eurRate, 2L, TimeUnit.HOURS);
        }

        return price.divide(new BigDecimal(eurRate.toString()), 2, RoundingMode.HALF_UP);
    }

    /**
     * 人民币转欧元(静态汇率)
     *
     * @param price
     * @return
     */
    public BigDecimal rmb2EurStatic(BigDecimal price, BigDecimal rate) {
        if (null == price) {
            return BigDecimal.ZERO;
        }
        rate = null == rate ? new BigDecimal(DEFAULT_EXCHANGE_RATE_EUR) : rate;
        if (rate.compareTo(BigDecimal.ZERO) == 0) rate = new BigDecimal(DEFAULT_EXCHANGE_RATE_EUR);

        return price.divide(rate, 2, RoundingMode.HALF_UP);
    }

    /**
     * 港元转人民币
     *
     * @param otPrice
     * @return
     */
    public BigDecimal hk2Rmb(BigDecimal otPrice) {
//        MoneyExchange moneyExchange = moneyExchangeService.getExchangeByName(hkName);
        // NumberUtil.toBigDecimal(moneyExchange != null?moneyExchange.getBankConversionPri():Constants.DEFAULT_EXCHANGE_RATE_HK);
        BigDecimal hk2Rmb = new BigDecimal(DEFAULT_EXCHANGE_RATE_HK);
        return otPrice.multiply(hk2Rmb).movePointLeft(2).setScale(2, RoundingMode.UP);
    }

    /**
     * 计算折扣率
     *
     * @param price
     * @param otPrice
     * @return
     */
    public BigDecimal calcDiscount(BigDecimal price, BigDecimal otPrice, BigDecimal rate) {
        if (otPrice == null || otPrice.intValue() == 0) {
            return null;
        }
        rate = null == rate ? new BigDecimal(DEFAULT_EXCHANGE_RATE_EUR) : rate;
        BigDecimal discount = price.divide(otPrice.multiply(rate), 2, BigDecimal.ROUND_UP).movePointRight(2).divide(new BigDecimal(10));
        if (discount != null && discount.doubleValue() == 0) {
            return null;
        }

        return discount;
    }


    /**
     * 计算商品售价
     *
     * @param products 商品集合
     * @param merId    商户id
     * @param areaType 收货区域
     */
    public Map<Integer, StoreProductMer> calcProductPrice(List<StoreProduct> products, Integer merId, Integer areaType) {
        try {
            if (null == merId || CollectionUtils.isEmpty(products)) {
                return new HashMap<>();
            }
            List<Integer> ids = new ArrayList<>();
            List<Integer> cateIdList = new ArrayList<>();
            List<Integer> supplierIds = new ArrayList<>();
            for (StoreProduct product : products) {
                ids.add(product.getId());
                if (!cateIdList.contains(product.getCateId())){
                    cateIdList.add(product.getCateId());
                }
                if (!supplierIds.contains(product.getSuppliersId())){
                    supplierIds.add(product.getSuppliersId());
                }
            }
            ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
            RatioVo ratioVo = getRatio(channelMerchant);
            Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
            // 判断是否有加价行为
            List<StoreProductMer> storeProductMers = storeProductMerService.list(Wrappers.<StoreProductMer>lambdaQuery()
                    .in(StoreProductMer::getProductId, ids)
            );
            Map<Integer, StoreProductMer> storeProductMerMap = storeProductMers.stream().collect(Collectors.toMap(StoreProductMer::getProductId,
                    s -> {
                        return s;
                    },
                    (StoreProductMer value1, StoreProductMer value2) -> {
                        return value1;
                    }
            ));

            //获取分类加价率
            List<ChannelCategoryConfig> channelCategoryConfigList = channelCategoryConfigService.list(Wrappers.lambdaQuery(ChannelCategoryConfig.class)
                    .eq(ChannelCategoryConfig::getMerId, merId)
                    .in(ChannelCategoryConfig::getCateId, cateIdList));
            Map<Integer, ChannelCategoryConfig> categoryConfigMap = channelCategoryConfigList.stream().collect(Collectors.toMap(ChannelCategoryConfig::getCateId, channelCategoryConfig -> channelCategoryConfig));
            // 获取分类头程费用
            List<CategoryMatch> categoryMatches = categoryMatchService.list(Wrappers.<CategoryMatch>lambdaQuery()
                    .in(CategoryMatch::getId, cateIdList));
            Map<Integer, CategoryMatch> categoryMatchMap = categoryMatches.stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
            Map<Integer, List<StoreProductAttrValue>> attrMap = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().in(StoreProductAttrValue::getProductId, ids)).stream().collect(Collectors.groupingBy(StoreProductAttrValue::getProductId));

            Map<Integer, Supplier> supplierMap = supplierService.listByIds(supplierIds).stream().collect(Collectors.toMap(Supplier::getId, e -> e, (v1, v2) -> v1));
            for (StoreProduct product : products) {
                //判断是否自建
                boolean isInside = supplier != null && Objects.equals(supplier.getId(), product.getSuppliersId()) && Objects.equals(product.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
                ProductVo productVo = new ProductVo();
                BeanUtils.copyProperties(product, productVo);
                //判断商户和供应商商品是否有关联
                ChannelMerchant relatedMerchant = null;
                try {
                    relatedMerchant = getRelatedMerchant(product.getSuppliersId(), channelMerchant.getId());
                }catch (Exception e){
                    log.error("获取商户关系异常: {}", JSON.toJSONString(product),e);
                }

                boolean freeShipping = false;
                if (Objects.nonNull(relatedMerchant)) {
                    //是否包邮
                    if (StringUtils.isNotBlank(relatedMerchant.getFreeIds())) {
                        freeShipping = Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(merId.toString());
                    }
                    //加价率
                    if (StringUtils.isNotBlank(relatedMerchant.getRateIds()) && Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(merId.toString())) {
                        productVo.setPlatRatio(relatedMerchant.getExtraRate());
                    }
                }
                if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                    BeanUtils.copyProperties(ratioVo, productVo);
                }
                //供应商关联商户
//            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping);
                productVo.setCategoryMatch(categoryMatchMap.get(productVo.getCateId()));
                //成本价（供应商供货的需要加上供应商的提点率作为成本价）
                BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, areaType, false);
                // 判断是否有加价行为
//            StoreProductMer storeProductMer = storeProductMerService.getOne(Wrappers.<StoreProductMer>lambdaQuery()
//                    .eq(StoreProductMer :: getProductId, product.getId())
//                    .last("LIMIT 1")
//            );
                // 冗余一个查表赋值逻辑
                StoreProductMer storeProductMer = storeProductMerMap.get(product.getId());
                checkMerProductStatus(product, storeProductMer);

                ChannelCategoryConfig channelCategoryConfig = new ChannelCategoryConfig();
                if ((null == storeProductMer || storeProductMer.getPriceType().equals(PriceTypeEnum.CATE.getCode())) || storeProductMer.getPriceType().equals(PriceTypeEnum.RAISE.getCode()) && !isInside) {
                    ChannelCategoryConfig config = categoryConfigMap.get(product.getCateId());
                    if (config != null && config.getRatio() != null) {
                        channelCategoryConfig = config;
                    } else {
                        channelCategoryConfig.setRatio(BigDecimal.ZERO);
                    }
                }
//            Integer priceTailNumber = getPriceTailNumber(channelMerchant, storeProductMer);
//            productVo.setPriceTailNumber(priceTailNumber);
                //计算售价
                calculatePrice(productVo, isInside, storeProductMer, channelCategoryConfig, null);
                BeanUtils.copyProperties(productVo, product);
                //头程物流
                BigDecimal firstPrice = getFirstPriceNew(product.getIsEurope(), product.getTempId(), areaType, channelMerchant, freeShipping, categoryMatchMap.get(product.getCateId()), product.getSuppliersId());
                //二段物流
                BigDecimal weight = getProductWeight(attrMap.get(product.getId()));
                Supplier productSupplier = supplierMap.get(product.getSuppliersId());
                BigDecimal secondPrice = getSecondPriceNew(product, areaType, channelMerchant, freeShipping, productSupplier.getId(), weight,
                        productSupplier.getDirectMailType(), productVo.getPrice(), null, null);
                BigDecimal priceAddPost = product.getPrice().add(firstPrice).add(secondPrice);
                //税费
                BigDecimal taxPrice = getTaxPriceNew(product, areaType,
                        priceAddPost, channelMerchant, merCost, freeShipping, false, true);
                //税费 + 二段物流费用 + 一段物流费用
                BigDecimal taxAndSecondPrice = taxPrice.add(firstPrice).add(secondPrice);
                product.setTaxAndSecondPrice(taxAndSecondPrice);
                product.setSecondPrice(secondPrice);
                product.setTaxPrice(taxPrice);
                product.setFirstPrice(firstPrice);
            }
            return storeProductMerMap;

        }catch (Exception e){
            log.error("计算商品售价: ",e);
        }
        return null;


    }



    public Map<Integer, StoreProductMer> calcProductPriceV2(List<StoreProduct> products, final Integer merId, Integer areaType) {
        if (null == merId || CollectionUtils.isEmpty(products)) {
            return new HashMap<>();
        }
        final List<Integer> ids = new ArrayList<>();
        final List<Integer> cateIdList = new ArrayList<>();
        final List<Integer> supplierIds = new ArrayList<>();
        for (StoreProduct product : products) {
            ids.add(product.getId());
            if (!cateIdList.contains(product.getCateId())){
                cateIdList.add(product.getCateId());
            }
            if (!supplierIds.contains(product.getSuppliersId())){
                supplierIds.add(product.getSuppliersId());
            }
        }
        final ChannelMerchant channelMerchant = new ChannelMerchant();
        final RatioVo ratioVo = new RatioVo();
        CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{
            try {
                // 商户数据
                ChannelMerchant tmpChannelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
                if (tmpChannelMerchant != null) {
                    BeanUtils.copyProperties(tmpChannelMerchant, channelMerchant);
                }

                // 加价率
                RatioVo tmpRatioVo = getRatio(channelMerchant);
                if (tmpRatioVo != null) {
                    BeanUtils.copyProperties(tmpRatioVo, ratioVo);
                }
            } catch (Exception e) {
                // 异常处理逻辑，例如记录日志或通知监控系统
                log.error("Error occurred during async processing", e);
            }
        },executorService);
        final Supplier supplier = new Supplier();
        final Map<Integer, StoreProductMer> storeProductMerMap = new HashMap<>();
        final Map<Integer, Supplier> supplierMap = new HashMap<>();
        CompletableFuture<Void> completableFuture2 = CompletableFuture.runAsync(()->{
            // 供应商
            Supplier supplierTmp = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
            if (null != supplierTmp){
                BeanUtils.copyProperties(supplierTmp, supplier);
            }
            // 获取商户商品
            MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(merId));
            Map<Integer, StoreProductMer> storeProductMerMapTmp = getStoreProductMerMap(ids);
            if (MapUtils.isNotEmpty(storeProductMerMapTmp)){
                storeProductMerMap.putAll(storeProductMerMapTmp);
            }
            // 供应商信息
            Map<Integer, Supplier> supplierMapTmp = getSupplierMap(supplierIds);
            if (MapUtils.isNotEmpty(supplierMapTmp)){
                supplierMap.putAll(supplierMapTmp);
            }
        },executorService);
        final Map<Integer, ChannelCategoryConfig> categoryConfigMap = new HashMap<>();
        final Map<Integer, CategoryMatch> categoryMatchMap = new HashMap<>();
        final Map<Integer, List<StoreProductAttrValue>> attrMap = new HashMap<>();
        CompletableFuture<Void> completableFuture3 = CompletableFuture.runAsync(() -> {
            // 获取类目配置
            Map<Integer, ChannelCategoryConfig> categoryConfigMapTmp = getCategoryConfigMap(merId, cateIdList);
            if (MapUtils.isNotEmpty(categoryConfigMapTmp)) {
                categoryConfigMap.putAll(categoryConfigMapTmp);
            }
            // 获取类目
            Map<Integer, CategoryMatch> categoryMatchMapTmp = getCategoryMatchMap(cateIdList);
            if (MapUtils.isNotEmpty(categoryMatchMapTmp)) {
                categoryMatchMap.putAll(categoryMatchMapTmp);
            }
            // 商品sku信息
            Map<Integer, List<StoreProductAttrValue>> attrMapTmp = getAttrMap(ids);
            if (MapUtils.isNotEmpty(attrMapTmp)) {
                attrMap.putAll(attrMapTmp);
            }
        });

        // 等待线程执行完
        CompletableFuture.allOf(completableFuture3,completableFuture2,completableFuture1).join();

        for (StoreProduct product : products) {
            //判断是否自建
            boolean isInside = supplier != null && Objects.equals(supplier.getId(), product.getSuppliersId()) && Objects.equals(product.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(product, productVo);
            //判断商户和供应商商品是否有关联
            ChannelMerchant relatedMerchant = getRelatedMerchant(product.getSuppliersId(), channelMerchant.getId());
            boolean freeShipping = false;
            if (Objects.nonNull(relatedMerchant)) {
                //是否包邮
                if (StringUtils.isNotBlank(relatedMerchant.getFreeIds())) {
                    freeShipping = Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(merId.toString());
                }
                //加价率
                if (StringUtils.isNotBlank(relatedMerchant.getRateIds()) && Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(merId.toString())) {
                    productVo.setPlatRatio(relatedMerchant.getExtraRate());
                }
            }
            if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                BeanUtils.copyProperties(ratioVo, productVo);
            }
            productVo.setCategoryMatch(categoryMatchMap.get(productVo.getCateId()));
            //成本价（供应商供货的需要加上供应商的提点率作为成本价）
            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, areaType, false);
            // 冗余一个查表赋值逻辑
            StoreProductMer storeProductMer = storeProductMerMap.get(product.getId());
            checkMerProductStatus(product, storeProductMer);

            ChannelCategoryConfig channelCategoryConfig = new ChannelCategoryConfig();
            if ((null == storeProductMer || storeProductMer.getPriceType().equals(PriceTypeEnum.CATE.getCode())) || storeProductMer.getPriceType().equals(PriceTypeEnum.RAISE.getCode()) && !isInside) {
                ChannelCategoryConfig config = categoryConfigMap.get(product.getCateId());
                if (config != null && config.getRatio() != null) {
                    channelCategoryConfig = config;
                } else {
                    channelCategoryConfig.setRatio(BigDecimal.ZERO);
                }
            }
//            Integer priceTailNumber = getPriceTailNumber(channelMerchant, storeProductMer);
//            productVo.setPriceTailNumber(priceTailNumber);
            //计算售价
            calculatePrice(productVo, isInside, storeProductMer, channelCategoryConfig, null);
            BeanUtils.copyProperties(productVo, product);
            //头程物流
            BigDecimal firstPrice = getFirstPriceNew(product.getIsEurope(), product.getTempId(), areaType, channelMerchant, freeShipping, categoryMatchMap.get(product.getCateId()), product.getSuppliersId());
            //二段物流
            BigDecimal weight = getProductWeight(attrMap.get(product.getId()));
            Supplier productSupplier = supplierMap.get(product.getSuppliersId());
            BigDecimal secondPrice = getSecondPriceNew(product, areaType, channelMerchant, freeShipping, productSupplier.getId(), weight,
                    productSupplier.getDirectMailType(), productVo.getPrice(), null, null);
            BigDecimal priceAddPost = product.getPrice().add(firstPrice).add(secondPrice);
            //税费
            BigDecimal taxPrice = getTaxPriceNew(product, areaType,
                    priceAddPost, channelMerchant, merCost, freeShipping, false, true);
            //税费 + 二段物流费用 + 一段物流费用
            BigDecimal taxAndSecondPrice = taxPrice.add(firstPrice).add(secondPrice);
            product.setTaxAndSecondPrice(taxAndSecondPrice);
            product.setFirstPrice(firstPrice);
        }

        return storeProductMerMap;
    }

    private Map<Integer, Supplier> getSupplierMap(List<Integer> supplierIds) {
        List<Supplier> suppliers = supplierService.listByIds(supplierIds);
        if (CollectionUtils.isEmpty(supplierIds)){
            return new HashMap<>();
        }
        return suppliers.stream().collect(Collectors.toMap(Supplier::getId, e -> e, (v1, v2) -> v1));
    }

    private Map<Integer, List<StoreProductAttrValue>> getAttrMap(List<Integer> ids) {
        List<StoreProductAttrValue> list = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().in(StoreProductAttrValue::getProductId, ids));
        if (CollectionUtils.isEmpty(list)){
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.groupingBy(StoreProductAttrValue::getProductId));
    }

    private Map<Integer, CategoryMatch> getCategoryMatchMap(List<Integer> cateIdList) {
        List<CategoryMatch> categoryMatches = categoryMatchService.list(Wrappers.<CategoryMatch>lambdaQuery()
                .in(CategoryMatch::getId, cateIdList));
        if (CollectionUtils.isEmpty(categoryMatches)){
            return new HashMap<>();
        }
        return categoryMatches.stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
    }

    private Map<Integer, ChannelCategoryConfig> getCategoryConfigMap(Integer merId, List<Integer> cateIdList) {
        List<ChannelCategoryConfig> channelCategoryConfigList = channelCategoryConfigService.list(Wrappers.lambdaQuery(ChannelCategoryConfig.class)
                .eq(ChannelCategoryConfig::getMerId, merId)
                .in(ChannelCategoryConfig::getCateId, cateIdList));
        if (CollectionUtils.isEmpty(channelCategoryConfigList)){
            return new HashMap<>();
        }
        return channelCategoryConfigList.stream().collect(Collectors.toMap(ChannelCategoryConfig::getCateId, channelCategoryConfig -> channelCategoryConfig));
    }

    private Map<Integer, StoreProductMer> getStoreProductMerMap(List<Integer> ids) {
        List<StoreProductMer> storeProductMers = storeProductMerService.list(Wrappers.<StoreProductMer>lambdaQuery()
                .in(StoreProductMer::getProductId, ids)
        );
        if (CollectionUtils.isEmpty(storeProductMers)){
            return new HashMap<>();
        }
        return storeProductMers.stream().collect(Collectors.toMap(StoreProductMer::getProductId,
                s -> s,
                (StoreProductMer value1, StoreProductMer value2) -> value1
        ));
    }

    public ChannelMerchant getRelatedMerchant(Integer suppliersId, Integer merId) {
        if (null != merId && null != suppliersId) {
            ChannelMerchant channelMerchant = channelMerchantService.getMerchantByRelated(3, "[" + suppliersId + "]");
            if (Objects.isNull(channelMerchant)) {
                channelMerchant = channelMerchantService.getOne(Wrappers.<ChannelMerchant>lambdaQuery()
                        .eq(ChannelMerchant::getChannelType, 3)
                        .eq(ChannelMerchant::getSuppliersIds, "[" + suppliersId + "]")
                        .last("LIMIT 1")
                );
                if (Objects.nonNull(channelMerchant)) {
                    redisUtil.set(Constants.CHANNEL_MERCHANT + channelMerchant.getId(), channelMerchant, 24L, TimeUnit.HOURS);
                }
            }
            return channelMerchant;
        }
        return null;
    }

    public boolean freeShipping(Integer suppliersId, Integer merId) {
        ChannelMerchant relatedMerchant = getRelatedMerchant(suppliersId, merId);
        if (Objects.nonNull(relatedMerchant) && StringUtils.isNotBlank(relatedMerchant.getFreeIds())) {
            return Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(merId.toString());
        }
        return false;
    }

    /**
     * 计算商户售价
     *
     * @param productVo             商品
     * @param isInside              是否自建
     * @param storeProductMer       商户商品信息
     * @param channelCategoryConfig 分类加价率
     * @param list                  商品规格标识
     */
    public void calculatePrice(ProductVo productVo, boolean isInside, StoreProductMer storeProductMer, ChannelCategoryConfig channelCategoryConfig, List<Boolean> list) {
        //商户售价
        BigDecimal merPrice;
        //默认分类加价
        BigDecimal ratio = null == channelCategoryConfig || null == channelCategoryConfig.getRatio() ? BigDecimal.ZERO : channelCategoryConfig.getRatio();
        if (null == storeProductMer || storeProductMer.getPriceType().equals(PriceTypeEnum.CATE.getCode())) {
            //自建商品
            if (isInside) {
                merPrice = productVo.getPrice();
                productVo.setMarkupType(1);
            } else {
                merPrice = productVo.getCost().multiply(ratio.movePointLeft(2).add(BigDecimal.ONE)).setScale(2, RoundingMode.HALF_UP);
                productVo.setMarkupType(0);
                productVo.setPriceChange(ratio);
            }
        } else if (storeProductMer.getPriceType().equals(PriceTypeEnum.MARKUP.getCode())) {
            if (isInside) {
                throw new CrmebException("自建商品" + productVo.getId() + "加价方式异常");
            } else {
                merPrice = productVo.getCost().multiply(storeProductMer.getPrice().movePointLeft(2).add(BigDecimal.ONE)).setScale(2, RoundingMode.HALF_UP);
            }
            productVo.setMarkupType(storeProductMer.getPriceType());
            productVo.setPriceChange(storeProductMer.getPrice());
        } else if (storeProductMer.getPriceType().equals(PriceTypeEnum.DISCOUNT.getCode())) {
            merPrice = eur2RmbStatic(productVo.getOtPrice(), productVo.getExchangeRate()).multiply(storeProductMer.getPrice().movePointLeft(1)).setScale(2, RoundingMode.HALF_UP);
            productVo.setMarkupType(storeProductMer.getPriceType());
            productVo.setPriceChange(storeProductMer.getPrice());
        } else if (storeProductMer.getPriceType().equals(PriceTypeEnum.FIXED.getCode())) {
            if (CollectionUtils.isEmpty(list)) {
                //最低价格
                merPrice = storeProductMer.getPrice();
                productVo.setMarkupType(storeProductMer.getPriceType());
            } else {
                list.clear();
                list.add(true);
                if (productVo.getProductValueMerMap().containsKey(productVo.getSourceSkuId())) {
                    merPrice = productVo.getProductValueMerMap().get(productVo.getSourceSkuId()).getPrice();
                    productVo.setMarkupType(storeProductMer.getPriceType());
                } else {
                    merPrice = productVo.getCost().multiply(ratio.movePointLeft(2).add(BigDecimal.ONE)).setScale(2, RoundingMode.HALF_UP);
                    productVo.setMarkupType(0);
                    productVo.setPriceChange(ratio);
                }
            }
        } else if (storeProductMer.getPriceType().equals(PriceTypeEnum.RAISE.getCode())) {
            merPrice = productVo.getCost().add(storeProductMer.getPrice());
            productVo.setMarkupType(storeProductMer.getPriceType());
        } else {
            throw new CrmebException("商品" + productVo.getId() + "加价方式异常");
        }
        if (BigDecimal.ZERO.compareTo(merPrice) > 0) {
            throw new CrmebException("售价异常");
        }
//        if(productVo.getPriceTailNumber() != null){
//            int bit = merPrice.intValue() % 10;
//            int carry = merPrice.intValue() - bit + productVo.getPriceTailNumber();
//            merPrice = BigDecimal.valueOf(productVo.getPriceTailNumber() < bit ? carry + 10 : carry);
//        }
        productVo.setPrice(merPrice);
    }

    /**
     * 计算商户成本价
     *
     * @param channelMerchant 商户
     * @param productVo       商品
     * @param isInside        是否自建
     * @return 商户成本
     */
    public BigDecimal calculateCostPrice(ChannelMerchant channelMerchant, ProductVo productVo, boolean isInside, boolean freeShipping, Integer areaType, boolean isPicking) {
        //平台加价价格
        BigDecimal platPrice;
        //商户成本
        BigDecimal merCost;
        //首段物流
        BigDecimal firstPrice;
        if (isInside) {
            merCost = productVo.getCost();
            firstPrice = BigDecimal.ZERO;
        } else {
            platPrice = productVo.getCost().add(productVo.getCost().multiply(productVo.getPlatRatio().movePointLeft(2)).setScale(2, RoundingMode.HALF_UP));
            //首段物流
//            firstPrice = getFirstPrice(productVo.getIsEurope(), productVo.getTempId(), channelMerchant,freeShipping,productVo.getSuppliersName());
            firstPrice = getFirstPriceNew(productVo.getIsEurope(), productVo.getTempId(), areaType, channelMerchant, freeShipping, productVo.getCategoryMatch(), productVo.getSuppliersId());

            //平台供货价格
            //merCost = platPrice.add(firstPrice);
            merCost = platPrice;
            if (channelMerchant.getAgentId() != 0) {
                //一级供应商成本价
                productVo.setFirstAgentCost(merCost);
                //判断
                if (productVo.getFirstAgentRatio() != null) {
                    merCost = merCost.multiply(productVo.getFirstAgentRatio().movePointLeft(2).add(BigDecimal.ONE)).setScale(2, RoundingMode.HALF_UP);
                }
                if (productVo.getSecondAgentRatio() != null) {
                    //二级供应商成本价
                    productVo.setSecondAgentCost(merCost);
                    merCost = merCost.multiply(productVo.getSecondAgentRatio().movePointLeft(2).add(BigDecimal.ONE)).setScale(2, RoundingMode.HALF_UP);
                }
            }
            //商户成本价
            productVo.setCost(merCost);
        }
        productVo.setFirstPrice(firstPrice);
        return merCost;
    }

    /**
     * 获取加价率
     *
     * @param channelMerchant 商户信息
     * @return 加价率
     */
    public RatioVo getRatio(ChannelMerchant channelMerchant) {
        RatioVo ratioVo = new RatioVo();
        MarkupRateRequest markupRateRequest = new MarkupRateRequest();
        markupRateRequest.setMerId(channelMerchant.getId());
        markupRateRequest.setType(1);
        BigDecimal ratio = markupRateService.selectMerchantRatio(markupRateRequest);
        BigDecimal platRatio,
                firstAgentRatio = null,
                secondAgentRatio = null;
        //上级代理
        if (channelMerchant.getAgentId() == 0) {
            //平台
            platRatio = ratio;
        } else {
            Agent firstAgent = agentService.getById(channelMerchant.getAgentId());
            //判断几级服务商
            if (firstAgent.getParentId() == 0) {
                //一级服务商
                ratioVo.setFirstAgentId(firstAgent.getId());
                platRatio = BigDecimal.valueOf(firstAgent.getRatio());
                firstAgentRatio = ratio;
            } else {
                //二级服务商
                ratioVo.setSecondAgentId(firstAgent.getId());
                //一级
                Agent secondAgent = agentService.getById(firstAgent.getParentId());
                ratioVo.setFirstAgentId(secondAgent.getId());
                platRatio = BigDecimal.valueOf(secondAgent.getRatio());
                firstAgentRatio = BigDecimal.valueOf(firstAgent.getRatio());
                secondAgentRatio = ratio;
            }
        }
        ratioVo.setPlatRatio(platRatio);
        ratioVo.setFirstAgentRatio(firstAgentRatio);
        ratioVo.setSecondAgentRatio(secondAgentRatio);
        return ratioVo;
    }


    /**
     * 获取商品尾号
     *
     * @param channelMerchant 商户信息
     * @param storeProductMer 商户商品信息
     * @return 尾号
     */
    public Integer getPriceTailNumber(ChannelMerchant channelMerchant, StoreProductMer storeProductMer) {
        Integer priceTailNumber = null;
        if (storeProductMer != null && storeProductMer.getPriceTailNumber() != null && storeProductMer.getPriceTailNumber() != -1) {
            priceTailNumber = storeProductMer.getPriceTailNumber();
        }
        if (channelMerchant.getPriceTailNumber() != null && (storeProductMer == null || storeProductMer.getPriceTailNumber() == null)) {
            priceTailNumber = channelMerchant.getPriceTailNumber();
        }
        return priceTailNumber;
    }

    /**
     * 计算商品规格售价
     *
     * @param productValues 商品规格集合
     * @param merId         商户id
     * @param storeProduct  商品
     * @param areaType      收货区域
     */
    public void calcProductValuePrice(List<StoreProductAttrValue> productValues, Integer merId, StoreProduct storeProduct, Integer areaType,
                                      Map<Integer, StoreProductMer> storeProductMerMap, boolean isPicking, List<Integer> ids, Boolean isBtoC, UserAddress addressInfo) {
//        log.info("calcProductValuePrice：{},{}", merId, JSON.toJSONString(productValues));

        if (null == merId && CollectionUtils.isEmpty(productValues)) {
            return;
        }
        // 渠道商户
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
        RatioVo ratioVo = getRatio(channelMerchant);
        // 统计第一次价格, 后续相同则不进行计算
        BigDecimal firstValuePrice = productValues.get(0).getPrice();
        BigDecimal calcValuePrice = BigDecimal.ZERO;
        BigDecimal calcValueCost = productValues.get(0).getCost();
        BigDecimal calcValueTaxPrice = BigDecimal.ZERO;
        BigDecimal calcTaxPrice = BigDecimal.ZERO;
        //是否固定价格
        List<Boolean> list = new ArrayList<>();
        list.add(false);
        // 判断是否有加价行为
        StoreProductMer storeProductMer = null;
        if (null == storeProductMerMap) {
            storeProductMer = storeProductMerService.getOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, storeProduct.getId())
                    .last("LIMIT 1")
            );
        } else {
            storeProductMer = storeProductMerMap.get(storeProduct.getId());
        }
        Map<String, StoreProductValueMer> productValueMerMap = new HashMap<>();
        if (storeProductMer != null && storeProductMer.getPriceType().equals(PriceTypeEnum.FIXED.getCode())) {
            List<StoreProductValueMer> productValueMerList = storeProductValueMerService.list(Wrappers.lambdaQuery(StoreProductValueMer.class).eq(StoreProductValueMer::getProductId, storeProduct.getId()));
            if (CollectionUtils.isNotEmpty(productValueMerList)) {
//                productValueMerMap = productValueMerList.stream().collect(Collectors.toMap(StoreProductValueMer::getSourceSkuId, e -> e));
                productValueMerMap = productValueMerList.stream().collect(Collectors.toMap(StoreProductValueMer::getSourceSkuId, e -> e,
                        (v1, v2) -> v1.getCreateTime().compareTo(v2.getCreateTime()) > 0 ? v1 : v2));
            }
        }
        boolean isInside = supplier != null && Objects.equals(supplier.getId(), storeProduct.getSuppliersId()) && Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
        ChannelCategoryConfig channelCategoryConfig = new ChannelCategoryConfig();
        if (null == storeProductMer || !(storeProductMer.getPriceType().equals(PriceTypeEnum.MARKUP.getCode()) || storeProductMer.getPriceType().equals(PriceTypeEnum.DISCOUNT.getCode()))) {
            channelCategoryConfig = getChannelCategoryConfig(merId, storeProduct);
        }
        //判断商户和供应商商品是否有关联
        ChannelMerchant relatedMerchant = getRelatedMerchant(storeProduct.getSuppliersId(), channelMerchant.getId());
        boolean freeShipping = Objects.nonNull(relatedMerchant) && StringUtils.isNotBlank(relatedMerchant.getFreeIds()) && Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(Objects.requireNonNull(merId).toString());
        //满额包邮判断
        if (CollectionUtils.isNotEmpty(ids)) {
            ChannelFreeShippingActivity productInfo = channelFreeShippingActivityService.getProductInfo(storeProduct.getId(), merId);
            if (Objects.nonNull(productInfo)) {
                if (ids.contains(productInfo.getId())) {
                    freeShipping = true;
                }
            }
        }
        //头程物流
        CategoryMatch categoryMatch = categoryMatchService.getById(storeProduct.getCateId());
        BigDecimal firstPrice = getFirstPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, categoryMatch, storeProduct.getSuppliersId());

        //二段物流 去掉2023.3.23
//        BigDecimal secondPrice = getSecondPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, storeProduct.getCateId(), storeProduct.getSuppliersId(),isPicking);
        //个位
//        Integer priceTailNumber = getPriceTailNumber(channelMerchant, storeProductMer);
        Supplier productSupplier = supplierService.getById(storeProduct.getSuppliersId());
        for (StoreProductAttrValue value : productValues) {
            // 价格相同则直接赋值
            if (value.getPrice().compareTo(firstValuePrice) == 0 && BigDecimal.ZERO.compareTo(calcValuePrice) < 0 && !list.get(0) && value.getCost().compareTo(calcValueCost) == 0) {
                value.setPrice(calcValuePrice);
                value.setCost(calcValueCost);
                value.setTaxPrice(calcTaxPrice);
                value.setTaxAndSecondPrice(calcValueTaxPrice);
                continue;
            }
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(value, productVo);
            if (Objects.nonNull(relatedMerchant)) {
                if (StringUtils.isNotBlank(relatedMerchant.getRateIds())) {
                    if (Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(Objects.requireNonNull(merId).toString())) {
                        productVo.setPlatRatio(relatedMerchant.getExtraRate());
                        value.setSuppliersRatio(relatedMerchant.getExtraRate());
                    }
                }
            }
            if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                BeanUtils.copyProperties(ratioVo, productVo);
                value.setRealPlatRatio(ratioVo.getPlatRatio());
            }
            productVo.setSuppliersName(storeProduct.getSuppliersName());
            productVo.setIsEurope(storeProduct.getIsEurope());
            productVo.setCateId(storeProduct.getCateId());
            productVo.setTempId(storeProduct.getTempId());
            productVo.setProductValueMerMap(productValueMerMap);
            productVo.setSourceCost(value.getSourceCost());
            productVo.setExchangeRate(storeProduct.getExchangeRate());
            //计算商户成本价
            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, areaType, isPicking);
//            productVo.setPriceTailNumber(priceTailNumber);
            //计算售价
            calculatePrice(productVo, isInside, storeProductMer, channelCategoryConfig, list);
            BeanUtils.copyProperties(productVo, value);

            BigDecimal secondPrice = getSecondPriceNew(storeProduct, areaType, channelMerchant, freeShipping, productSupplier.getId(), value.getWeight(),
                    productSupplier.getDirectMailType(), value.getPrice(), value.getSourceSkuId(), addressInfo);

            value.setSecondPrice(secondPrice);
            value.setFirstPrice(firstPrice);
            BigDecimal priceAddPost = value.getPrice().add(firstPrice).add(secondPrice);
            //税费
            BigDecimal taxPrice = getTaxPriceNew(storeProduct, areaType,
                    priceAddPost, channelMerchant, merCost, freeShipping, isPicking, isBtoC);
            value.setTaxPrice(taxPrice);
            //税费 + 二段物流费用 + 一段物流费用
            BigDecimal taxAndSecondPrice = taxPrice.add(secondPrice).add(firstPrice);
            value.setTaxAndSecondPrice(taxAndSecondPrice);
            // 赋值初始化价格
            if (BigDecimal.ZERO.compareTo(calcValuePrice) >= 0) {
                calcValuePrice = value.getPrice();
                calcValueCost = value.getCost();
                calcTaxPrice = value.getTaxPrice();
                calcValueTaxPrice = value.getTaxAndSecondPrice();
            }
            if (null == value.getFirstPrice() || BigDecimal.ZERO.compareTo(value.getFirstPrice()) == 0|| null == value.getSecondPrice() || BigDecimal.ZERO.compareTo(value.getSecondPrice())==0){
                log.warn("注意商品一二段金额为0");
            }
        }
    }
    /**
     * 计算商品规格售价
     *
     * @param productValues 商品规格集合
     * @param merId         商户id
     * @param storeProduct  商品
     * @param areaType      收货区域
     */
    public void calcProductValuePrice2(Map<Integer, Supplier>  supplierMap,Map<Integer, CategoryMatch> categoryMatchMap, Map<Integer, ChannelFreeShippingActivity> productInfoMap,Map<Integer, List<StoreProductValueMer>> merMap,ChannelMerchant channelMerchant, Supplier supplier, RatioVo ratioVo, List<StoreProductAttrValue> productValues, Integer merId, StoreProduct storeProduct, Integer areaType,
                                       Map<Integer, StoreProductMer> storeProductMerMap, boolean isPicking, List<Integer> ids, Boolean isBtoC, UserAddress addressInfo) {
        if (null == merId && CollectionUtils.isEmpty(productValues)) {
            return;
        }

        // 统计第一次价格, 后续相同则不进行计算
        BigDecimal firstValuePrice = productValues.get(0).getPrice();
        BigDecimal calcValuePrice = BigDecimal.ZERO;
        BigDecimal calcValueCost = productValues.get(0).getCost();
        BigDecimal calcValueTaxPrice = BigDecimal.ZERO;
        BigDecimal calcTaxPrice = BigDecimal.ZERO;
        //是否固定价格
        List<Boolean> list = new ArrayList<>();
        list.add(false);
        // 判断是否有加价行为
        StoreProductMer storeProductMer = null;
        if (null == storeProductMerMap) {
            storeProductMer = storeProductMerService.getOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, storeProduct.getId())
                    .last("LIMIT 1")
            );
        } else {
            storeProductMer = storeProductMerMap.get(storeProduct.getId());
        }
        Map<String, StoreProductValueMer> productValueMerMap = new HashMap<>();
        if (storeProductMer != null && storeProductMer.getPriceType().equals(PriceTypeEnum.FIXED.getCode())) {
            List<StoreProductValueMer> productValueMerList = merMap.get(storeProduct.getId());
            if (CollectionUtils.isNotEmpty(productValueMerList)) {
                productValueMerMap = productValueMerList.stream().collect(Collectors.toMap(StoreProductValueMer::getSourceSkuId, e -> e));
            }
        }
        boolean isInside = supplier != null && Objects.equals(supplier.getId(), storeProduct.getSuppliersId()) && Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
        ChannelCategoryConfig channelCategoryConfig = new ChannelCategoryConfig();
        if (null == storeProductMer || !(storeProductMer.getPriceType().equals(PriceTypeEnum.MARKUP.getCode()) || storeProductMer.getPriceType().equals(PriceTypeEnum.DISCOUNT.getCode()))) {
            channelCategoryConfig = getChannelCategoryConfig(merId, storeProduct);
        }
        //判断商户和供应商商品是否有关联
        ChannelMerchant relatedMerchant = getRelatedMerchant(storeProduct.getSuppliersId(), channelMerchant.getId());
        boolean freeShipping = Objects.nonNull(relatedMerchant) && StringUtils.isNotBlank(relatedMerchant.getFreeIds()) && Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(Objects.requireNonNull(merId).toString());
        //满额包邮判断
        if (CollectionUtils.isNotEmpty(ids)) {
            ChannelFreeShippingActivity productInfo = productInfoMap.get(storeProduct.getId());
            if (Objects.nonNull(productInfo)) {
                if (ids.contains(productInfo.getId())) {
                    freeShipping = true;
                }
            }
        }
        //头程物流
        CategoryMatch categoryMatch = categoryMatchMap.get(storeProduct.getCateId());
        BigDecimal firstPrice = getFirstPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, categoryMatch, storeProduct.getSuppliersId());

        //二段物流 去掉2023.3.23
//        BigDecimal secondPrice = getSecondPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, storeProduct.getCateId(), storeProduct.getSuppliersId(),isPicking);
        //个位
//        Integer priceTailNumber = getPriceTailNumber(channelMerchant, storeProductMer);
        Supplier productSupplier = supplierMap.get(storeProduct.getSuppliersId());
        for (StoreProductAttrValue value : productValues) {
            // 价格相同则直接赋值
            if (value.getPrice().compareTo(firstValuePrice) == 0 && BigDecimal.ZERO.compareTo(calcValuePrice) < 0 && !list.get(0) && value.getCost().compareTo(calcValueCost) == 0) {
                value.setPrice(calcValuePrice);
                value.setCost(calcValueCost);
                value.setTaxPrice(calcTaxPrice);
                value.setTaxAndSecondPrice(calcValueTaxPrice);
                continue;
            }
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(value, productVo);
            if (Objects.nonNull(relatedMerchant)) {
                if (StringUtils.isNotBlank(relatedMerchant.getRateIds())) {
                    if (Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(Objects.requireNonNull(merId).toString())) {
                        productVo.setPlatRatio(relatedMerchant.getExtraRate());
                        value.setSuppliersRatio(relatedMerchant.getExtraRate());
                    }
                }
            }
            if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                BeanUtils.copyProperties(ratioVo, productVo);
                value.setRealPlatRatio(ratioVo.getPlatRatio());
            }
            productVo.setSuppliersName(storeProduct.getSuppliersName());
            productVo.setIsEurope(storeProduct.getIsEurope());
            productVo.setCateId(storeProduct.getCateId());
            productVo.setTempId(storeProduct.getTempId());
            productVo.setProductValueMerMap(productValueMerMap);
            productVo.setSourceCost(value.getSourceCost());
            productVo.setExchangeRate(storeProduct.getExchangeRate());
            //计算商户成本价
            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, areaType, isPicking);
//            productVo.setPriceTailNumber(priceTailNumber);
            //计算售价
            calculatePrice(productVo, isInside, storeProductMer, channelCategoryConfig, list);
            BeanUtils.copyProperties(productVo, value);

            BigDecimal secondPrice = getSecondPriceNew(storeProduct, areaType, channelMerchant, freeShipping, productSupplier.getId(), value.getWeight(),
                    productSupplier.getDirectMailType(), value.getPrice(), value.getSourceSkuId(), addressInfo);

            value.setSecondPrice(secondPrice);
            value.setFirstPrice(firstPrice);
            //税费
            BigDecimal taxPrice = getTaxPriceNew(storeProduct,areaType,
                    value.getPrice().add(firstPrice).add(secondPrice), channelMerchant, merCost, freeShipping,
                    isPicking, isBtoC);
            value.setTaxPrice(taxPrice);
            //税费 + 二段物流费用 + 一段物流费用
            BigDecimal taxAndSecondPrice = taxPrice.add(secondPrice).add(firstPrice);
            value.setTaxAndSecondPrice(taxAndSecondPrice);
            // 赋值初始化价格
            if (BigDecimal.ZERO.compareTo(calcValuePrice) >= 0) {
                calcValuePrice = value.getPrice();
                calcValueCost = value.getCost();
                calcTaxPrice = value.getTaxPrice();
                calcValueTaxPrice = value.getTaxAndSecondPrice();
            }
            if (null == value.getFirstPrice() || BigDecimal.ZERO.compareTo(value.getFirstPrice()) == 0|| null == value.getSecondPrice() || BigDecimal.ZERO.compareTo(value.getSecondPrice())==0){
                log.warn("注意商品一二段金额为0");
            }
        }
    }

    /**
     * 由外层代码合并过来, 减少数据查询
     *
     * @author daigb
     * @date: 2022-04-29 15:59
     */
    private void checkMerProductStatus(StoreProduct product, StoreProductMer storeProductMer) {
        //查询商户商品的上下架状态和推荐状态
        if (product.getIsShow()) {
            if (!Objects.isNull(storeProductMer) && Objects.equals("1", storeProductMer.getIsNotShow())) {
                product.setIsShow(false);
            }
        }
        if (null == storeProductMer) {
            product.setIsBest(false);
            product.setRebateRate(BigDecimal.ZERO);
        } else {
            product.setIsBest(storeProductMer.getIsBest());
            product.setRebateRate(storeProductMer.getRebateRate());
        }
        if (null != storeProductMer) {
            product.setRecommendImg(storeProductMer.getRecommendImg());
            product.setShelfTime(storeProductMer.getUpdateTime());
        }
    }

    /**
     * 获取分类加价率
     *
     * @param merId        商户id
     * @param storeProduct 商品信息
     * @return 分类加价率
     */
    public ChannelCategoryConfig getChannelCategoryConfig(Integer merId, StoreProduct storeProduct) {
        ChannelCategoryConfig channelCategoryConfig;
        channelCategoryConfig = channelCategoryConfigService.getOne(Wrappers.lambdaQuery(ChannelCategoryConfig.class)
                .eq(ChannelCategoryConfig::getMerId, merId)
                .eq(ChannelCategoryConfig::getCateId, storeProduct.getCateId())
                .last("LIMIT 1")
        );
        if (channelCategoryConfig == null || channelCategoryConfig.getRatio() == null) {
            channelCategoryConfig = new ChannelCategoryConfig();
            channelCategoryConfig.setRatio(BigDecimal.ZERO);
        }
        return channelCategoryConfig;
    }

    /**
     * 获取首段物流费用
     * @param isEurope 商品来源id
     * @param tempId 发货地id
     * @return 首段物流费用
     */
//    public BigDecimal getFirstPrice(Integer isEurope,Integer tempId, ChannelMerchant channelMerchant, boolean freeShipping,String supplierName) {
//        BigDecimal firstPrice = BigDecimal.ZERO;
//        //包邮
//        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
//            return firstPrice;
//        }
//        if(StringUtils.isBlank(supplierName)){
//            throw new CrmebException("该商品所属供应商异常");
//        }
//        //头程30.香港供应商/IM/奢批（非大陆发货的商品）
//        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            return Constants.HK_FIRST_PRICE;
//        }
//        //头程 20  会订货
//        if (Objects.equals(isEurope, ProductTypeEnum.ORANGE.getCode())) {
//            return Constants.CN_FIRST_PRICE;
//        }
//        //头程 20  奢批大陆
//        if (Objects.equals(isEurope, ProductTypeEnum.UNIBUY.getCode()) && StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            return Constants.CN_FIRST_PRICE;
//        }
//        //其他 0
//        return BigDecimal.ZERO;
//    }

    /**
     * 获取首段物流费用
     * @param isEurope 商品来源id
     * @param tempId 发货地id
     * @return 首段物流费用   2023.3.3修改
     */
//    public BigDecimal getFirstPrice(Integer isEurope,Integer tempId, Integer areaType,ChannelMerchant channelMerchant, boolean freeShipping,Integer cateId,String supplierName,boolean isPicking) {
//        BigDecimal firstPrice = BigDecimal.ZERO;
//        //包邮
//        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
//            return firstPrice;
//        }
//        if (StringUtils.isBlank(supplierName)) {
//            throw new CrmebException("该商品所属供应商异常");
//        }
//        //头程30.香港供应商/IM/奢批（非大陆发货的商品）
//        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            return Constants.HK_FIRST_PRICE;
//        }
//        //头程 20  会订货
//        if (Objects.equals(isEurope, ProductTypeEnum.ORANGE.getCode())) {
//            return Constants.CN_FIRST_PRICE;
//        }
//        //头程 20  奢批大陆
////        if (Objects.equals(isEurope, ProductTypeEnum.UNIBUY.getCode()) && StockAreaTempEnum.CN.getTempId().equals(tempId)) {
////            return Constants.CN_FIRST_PRICE;
////        }
//        if (Objects.equals(isEurope, ProductTypeEnum.UNIBUY.getCode()) || Objects.equals(isEurope, ProductTypeEnum.UNIBUY1.getCode()) && StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            return Constants.CN_FIRST_PRICE;
//        }
//        //其他 改成b类 二段运费
//        //欧洲供应商/诚品欧洲发货的商品：
//        if ((supplierName.startsWith("IT") || Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())) && StockAreaTempEnum.EUR.getTempId().equals(tempId)) {
//            Object redisCost = getCateBCost(cateId);
//            //收货地大陆 B分类价格 ; 2c 按收货地大陆算
//            //2023.3.10 去掉其他情况的 1.1倍计算
////            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
//                return (BigDecimal) redisCost;
////            } else {
////                //其他 A分类价格；  A=B*1.1
////                return new BigDecimal(redisCost.toString()).multiply(new BigDecimal(Constants.CATEGORY_A_MULTIPLE)).setScale(2, RoundingMode.UP);
////            }
//        }
//        //香港供应商/IM/奢批（非大陆发货的商品）：
////        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
////            //收货地大陆 B分类价格 / 2c 按收货地大陆算
////            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
////                Object redisCost = getCateBCost(cateId);
////                // -30
////                return new BigDecimal(redisCost.toString()).subtract(BigDecimal.valueOf(30));
////            }
////        }
//
//        return BigDecimal.ZERO;
//    }

//    /**
//     *
//     * @param tempId 发货地id
//     * @param areaType 收货地类型id
//     * @param price 售价
//     * @param channelMerchant 商户
//     * @param merCost 平台供货价
//     * @return 税费
//     */
//    public BigDecimal getTaxPrice(Integer isEurope, Integer tempId, Integer areaType, BigDecimal price, ChannelMerchant channelMerchant, BigDecimal merCost, boolean freeShipping, String supplierName,boolean isPicking) {
//        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
//            return BigDecimal.ZERO;
//        }
//        if(StringUtils.isBlank(supplierName)){
//            throw new CrmebException("该商品所属供应商异常");
//        }
//        //平台供货价大于售价,税费按供货价计算
//        if (merCost.compareTo(price) > 0) {
//            price = merCost;
//        }
//        //欧洲供应商/诚品欧洲发货的商品 ;/香港供应商/IM/奢批（非大陆发货的商品）; 收货地大陆  税费（售价*20%）
//        BigDecimal taxPrice = BigDecimal.ZERO;
//        //欧洲供应商/诚品供应商  (欧洲发货)
//        BigDecimal multiply = BigDecimal.ZERO;
//        int flag = Constants.TAX_RATE_THRESHOLD.compareTo(price);
//
//        //收货地非大陆 2023.3.7
//        if (!AreaTypeEnum.CN.getType().equals(areaType)) {
//            return BigDecimal.ZERO;
//        }
//
//        if(flag==-1){ //价格大于4400
//            multiply = price.multiply(new BigDecimal(Constants.DEFAULT_POSTAGE_RATE).movePointLeft(2)).setScale(2, RoundingMode.UP);
//        }else
//        {
//            multiply = price.multiply(new BigDecimal(Constants.BA_DEFAULT_POSTAGE_RATE).movePointLeft(2)).setScale(2, RoundingMode.UP);
//        }
//
//        if ((supplierName.startsWith("IT") || Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())) && StockAreaTempEnum.EUR.getTempId().equals(tempId)) {
//            //计算税费
//            taxPrice = multiply;
//            return taxPrice;
//        }
//        //香港供应商/IM/奢批（非大陆发货的商品）
//        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            taxPrice = multiply;
//            return taxPrice;
//        }
//        //国内保税仓&&香港保税仓
//        if (StockAreaTempEnum.BA_HK.getTempId().equals(tempId) || StockAreaTempEnum.BA_CH.getTempId().equals(tempId)){
//            taxPrice = price.multiply(new BigDecimal(Constants.BA_DEFAULT_POSTAGE_RATE).movePointLeft(2)).setScale(2, RoundingMode.UP);
//            return taxPrice;
//        }
//        //2C 一口价税费
//        if (channelMerchant.getAppletType() == 1 && !isPicking) {
//            return taxPrice;
//        }
//        //收货地大陆
//        if (AreaTypeEnum.CN.getType().equals(areaType)) {
//            return taxPrice;
//        }
//        //其他情况返回0
//        return BigDecimal.ZERO;
//    }


    /**
     * 获取第二段运费
     * @param isEurope 商品来源id
     * @param tempId 发货地id
     * @param areaType 收货区域类型
     * @return 第二段运费
     */
//    public BigDecimal getSecondPrice(Integer isEurope, Integer tempId, Integer areaType, ChannelMerchant channelMerchant, boolean freeShipping, Integer cateId, String supplierName,boolean isPicking) {
//
//        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
//            return BigDecimal.ZERO;
//        }
//        if(StringUtils.isBlank(supplierName)){
//            throw new CrmebException("该商品所属供应商异常");
//        }
//        //欧洲供应商/诚品欧洲发货的商品：
//        if ((supplierName.startsWith("IT") || Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())) && StockAreaTempEnum.EUR.getTempId().equals(tempId)) {
//            Object redisCost = getCateBCost(cateId);
//            //收货地大陆 B分类价格 ; 2c 按收货地大陆算
//            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
//                return (BigDecimal) redisCost;
//            } else {
//                //其他 A分类价格；  A=B*1.1
//                return new BigDecimal(redisCost.toString()).multiply(new BigDecimal(Constants.CATEGORY_A_MULTIPLE)).setScale(2, RoundingMode.UP);
//            }
//        }
//        //香港供应商/IM/奢批（非大陆发货的商品）：
//        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
//            //收货地大陆 B分类价格 / 2c 按收货地大陆算
//            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
//                Object redisCost = getCateBCost(cateId);
//                // -30
//                return new BigDecimal(redisCost.toString()).subtract(BigDecimal.valueOf(30));
//            }
//        }
//        //国内保税仓
//        if (StockAreaTempEnum.BA_CH.getTempId().equals(tempId)){
//            return new BigDecimal(10);
//        }
//        //香港保税仓
//        if (StockAreaTempEnum.BA_HK.getTempId().equals(tempId)){
//            return new BigDecimal(80);
//        }
//        //其他  包邮
//        return BigDecimal.ZERO;
//    }

//    /**
//     * 获取第二段运费
//     * @param isEurope 商品来源id
//     * @param tempId 发货地id
//     * @param areaType 收货区域类型
//     * @return 第二段运费 2023.3.3修改
//     */
//    public BigDecimal getSecondPrice(Integer isEurope, Integer tempId, Integer areaType, ChannelMerchant channelMerchant, boolean freeShipping, Integer cateId, String supplierName,boolean isPicking) {
//
//        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
//            return BigDecimal.ZERO;
//        }
//        if(StringUtils.isBlank(supplierName)){
//            throw new CrmebException("该商品所属供应商异常");
//        }
//
//            //香港收货没有打包费
////        if ((supplierName.startsWith("IT") || Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())) && StockAreaTempEnum.EUR.getTempId().equals(tempId)) {
////            Object redisCost = getCateBCost(cateId);
//            //收货地
//            if (AreaTypeEnum.HK.getType().equals(areaType)) {
//                return BigDecimal.ZERO;
//            } else {
//                return Constants.PACKING_FEE;
//            }
////        }
//
////        //欧洲供应商/诚品欧洲发货的商品：
////        if ((supplierName.startsWith("IT") || Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())) && StockAreaTempEnum.EUR.getTempId().equals(tempId)) {
////            Object redisCost = getCateBCost(cateId);
////            //收货地大陆 B分类价格 ; 2c 按收货地大陆算
////            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
////                return (BigDecimal) redisCost;
////            } else {
////                //其他 A分类价格；  A=B*1.1
////                return new BigDecimal(redisCost.toString()).multiply(new BigDecimal(Constants.CATEGORY_A_MULTIPLE)).setScale(2, RoundingMode.UP);
////            }
////        }
////        //香港供应商/IM/奢批（非大陆发货的商品）：
////        if (supplierName.startsWith("HK") && !StockAreaTempEnum.CN.getTempId().equals(tempId)) {
////            //收货地大陆 B分类价格 / 2c 按收货地大陆算
////            if (AreaTypeEnum.CN.getType().equals(areaType) || (channelMerchant.getAppletType() == 1 && !isPicking)) {
////                Object redisCost = getCateBCost(cateId);
////                // -30
////                return new BigDecimal(redisCost.toString()).subtract(BigDecimal.valueOf(30));
////            }
////        }
////        //国内保税仓
////        if (StockAreaTempEnum.BA_CH.getTempId().equals(tempId)){
////            return new BigDecimal(10);
////        }
////        //香港保税仓
////        if (StockAreaTempEnum.BA_HK.getTempId().equals(tempId)){
////            return new BigDecimal(80);
////        }
//        //其他  打包费
////        return Constants.PACKING_FEE;
//    }

    /**
     * 获取B分类运费价格
     *
     * @param cateId 分类id
     * @return 运费价格
     */
    private Object getCateBCost(Integer cateId) {
        Object redisCost = redisUtil.get(StrUtil.format(Constants.CATEGORY_B_COST_KEY, cateId));
        if (Objects.isNull(redisCost)) {
            FirstLogisticsCost firstLogisticsCost = firstLogisticsCostService.getOne(Wrappers.<FirstLogisticsCost>lambdaQuery().eq(FirstLogisticsCost::getCateId, cateId).last("LIMIT 1"));
            redisCost = Objects.isNull(firstLogisticsCost) ? BigDecimal.ZERO : firstLogisticsCost.getHighCost();
            redisUtil.set(StrUtil.format(Constants.CATEGORY_B_COST_KEY, cateId), redisCost, 48L, TimeUnit.HOURS);
        }
        return redisCost;
    }

    /**
     * 包邮判断
     *
     * @param isEurope        商品来源
     * @param channelMerchant 商户信息
     * @param tempId          发货地
     * @return 是否包邮
     */
    public boolean freeDelivery(Integer isEurope, ChannelMerchant channelMerchant, Integer tempId) {
        //自建商品跳过计算  2023.6.13暂时去掉这个判断
//        if (Objects.equals(isEurope, ProductTypeEnum.INSIDE.getCode()) && !Objects.equals(tempId, 14) && !Objects.equals(tempId, 15)) {
//            return true;
//        }
//        //橙子商品不计算
//        if (Objects.equals(isEurope, ProductTypeEnum.ORANGE.getCode())) {
//            return true;
//        }
        //墨宝不计算
        if (Objects.equals(channelMerchant.getId(), 25)) {
            return true;
        }
        //海淘品质生活
        if (Objects.equals(channelMerchant.getId(), 50)) {
            return true;
        }
        //海外供应商商户不计算
        if (Objects.equals(channelMerchant.getChannelType(), 8)) {
            return true;
        }
//        //吉客云推送商品,其他商户国内发货不计算物流费用
//        if(Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())){
//            return StockAreaTempEnum.CN.getTempId().equals(tempId) || StockAreaTempEnum.HK.getTempId().equals(tempId);
//        }

//        //吉客云推送商品； 8f品牌专营店，8f买手店 2个商户不计算物流费用；其他商户国内发货不计算物流费用
//        if(Objects.equals(isEurope, ProductTypeEnum.JKY.getCode())){
//            if(Objects.equals(channelMerchant.getId(), 18) || Objects.equals(channelMerchant.getId(), 30)){
//                return true;
//            }else {
//                return StockAreaTempEnum.CN.getTempId().equals(tempId) || StockAreaTempEnum.HK.getTempId().equals(tempId);
//            }
//        }
        return false;
    }

    /**
     * 订单价格计算
     *
     * @param storeCartResponse 购物车商品列表
     * @param userAddress       用户收货地址信息
     * @return 价格
     */
    public PriceGroupResponse getOrderPriceGroup(List<StoreCartResponse> storeCartResponse, UserAddress userAddress, Integer merId) {
        PriceGroupResponse priceGroupResponse = new PriceGroupResponse();
        BigDecimal storePostage = BigDecimal.ZERO, // 运费
                totalPrice = BigDecimal.ZERO, // 订单总金额
                packagePrice = BigDecimal.ZERO, // 订单总金额
//                vipPrice = BigDecimal.ZERO, // 订单会员优惠价
                costPrice = BigDecimal.ZERO, // 商户成本价
                sourceCostPrice = BigDecimal.ZERO, // 平台成本价
                firstPrice = BigDecimal.ZERO, // 首段物流
                secondPrice = BigDecimal.ZERO, // 二段物流
                taxPrice = BigDecimal.ZERO,  //税费
                taxAndSecondPrice;  //税费 + 一段物流费用 + 二段物流费用
        //收货时间集合
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        Set<String> set = new HashSet<>();
        Integer pickingId = 0;
        //收货区域
        Integer areaType = null;
        //满额包邮满足条件的活动id
        List<Integer> freeShippingActivityIds = channelFreeShippingActivityService.getFreeShippingActivityId(storeCartResponse, userAddress, merId);
        List<Integer> cateId = storeCartResponse.stream().map(StoreCartResponse::getProductInfo).map(StoreProductCartProductInfoResponse::getCateId).distinct().collect(Collectors.toList());
        Map<Integer, CategoryMatch> categoryMatchMap = categoryMatchService.getByIds(cateId).stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
        List<Integer> supplierIds = storeCartResponse.stream().map(StoreCartResponse::getProductInfo).map(StoreProductCartProductInfoResponse::getSuppliersId).distinct().collect(Collectors.toList());
        Map<Integer, Supplier> supplierMap = supplierService.listByIds(supplierIds).stream().collect(Collectors.toMap(Supplier::getId, e -> e, (v1, v2) -> v1));
        for (StoreCartResponse cartResponse : storeCartResponse) {
            StoreProductCartProductInfoResponse product = cartResponse.getProductInfo();
            // TODO DIDIOK PRICE -5
            totalPrice = (totalPrice.add(cartResponse.getTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))));
            if(null == cartResponse.getPackagePrice()){
                cartResponse.setPackagePrice(BigDecimal.ZERO);
            }
            packagePrice = (packagePrice.add(cartResponse.getPackagePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))));
            if (product == null) {
                continue;
            }
            pickingId = cartResponse.getPickingId();
            if (pickingId > 0) {
                //按批采收货方式计算
                areaType = cartResponse.getReceiptType();
            } else {
                if (userAddress == null && Objects.equals(channelMerchant.getAppletType(), 0) && !Objects.equals(channelMerchant.getId(), 40)) {
                    continue;
                }
                if (userAddress != null) {
                    areaType = userAddress.getAreaType();
                } else if (Objects.equals(channelMerchant.getId(), 40)) {
                    areaType = AreaTypeEnum.CN.getType();
                }
            }
            //商品是否包邮
            boolean freeShipping = freeShipping(product.getSuppliersId(), channelMerchant.getId());
            //满额包邮判断
            if (CollectionUtils.isNotEmpty(freeShippingActivityIds)) {
                //满额包邮判断 商品所属满额包邮活动
                ChannelFreeShippingActivity productInfo = channelFreeShippingActivityService.getProductInfo(product.getId(), merId);
                if (Objects.nonNull(productInfo)) {
                    if (freeShippingActivityIds.contains(productInfo.getId())) {
                        freeShipping = true;
                    }
                }
            }

            //设置收货时间
            String receivingTime = productUtil.getReceivingTime(product.getTempId(), product.getIsEurope(), product.getMerId(), product.getId());
            set.add(receivingTime);
//            if (product.getIsEurope() == 1 && Objects.equals(product.getMerId(), merId) && !Objects.equals(product.getTempId(), 14) && !Objects.equals(product.getTempId(), 15)) {
//                continue;
//            }
            //平台成本价
            sourceCostPrice = (sourceCostPrice.add(cartResponse.getSourceCostPrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))));
            //商户成本价
            costPrice = (costPrice.add((cartResponse.getCostPrice()).multiply(BigDecimal.valueOf(cartResponse.getCartNum()))));
//            vipPrice = (vipPrice.add(cartResponse.getVipTruePrice().multiply(BigDecimal.valueOf(cartResponse.getCartNum()))));
            //首段物流价格
            BigDecimal first = getFirstPriceNew(product.getIsEurope(), product.getTempId(), areaType, channelMerchant, freeShipping, categoryMatchMap.get(product.getCateId()), product.getSuppliersId());
            firstPrice = firstPrice.add(first.multiply(BigDecimal.valueOf(cartResponse.getCartNum())));
            //税费
            BigDecimal truePrice = cartResponse.getTruePrice();
            if (Objects.nonNull(cartResponse.getChannelActivity())) {
                truePrice = cartResponse.getProductInfo().getPrice();
            }
            if (Objects.nonNull(cartResponse.getActivityGroupId())) {
                truePrice = cartResponse.getProductInfo().getPrice();
            }
            //二段物流
            //获取购物车商品的重量
            BigDecimal weight = getProductWeightByStoreCar(cartResponse.getProductId(), cartResponse.getProductAttrUnique());
            Supplier supplier = supplierMap.get(product.getSuppliersId());
            StoreProduct storeProduct = storeProductDAO.selectById(product.getId());
            BigDecimal second = getSecondPriceNew(storeProduct, areaType, channelMerchant,
                    freeShipping, supplier.getId(), weight, supplier.getDirectMailType(), truePrice, cartResponse.getProductAttrUnique(), userAddress);
            secondPrice = secondPrice.add(second.multiply(BigDecimal.valueOf(cartResponse.getCartNum())));

            BigDecimal tax = getTaxPriceNew(storeProduct, areaType,
                    truePrice.add(first).add(second), channelMerchant, cartResponse.getCostPrice(), freeShipping, pickingId > 0, cartResponse.getIsBtoC());

            taxPrice = taxPrice.add(tax.multiply(BigDecimal.valueOf(cartResponse.getCartNum())));

            cartResponse.setTaxAndSecondPrice(tax.add(second).add(first));
        }
        priceGroupResponse.setFirstPrice(firstPrice);
        priceGroupResponse.setSecondPrice(secondPrice);

        //税费 + 二段物流费用 + 一段物流费用
        taxAndSecondPrice = taxPrice.add(secondPrice).add(firstPrice);
        priceGroupResponse.setTaxAndSecondPrice(taxAndSecondPrice);

        log.info(">>>> 一段物流: {}, 二段物流: {}, 税费: {}, 总和运税费: {} <<<<", firstPrice, secondPrice, taxPrice, taxAndSecondPrice);

        //运费
        priceGroupResponse.setStorePostage(storePostage.add(firstPrice).add(secondPrice).setScale(2, RoundingMode.UP));
        //税费字段添加
        priceGroupResponse.setTaxPrice(taxPrice);

        priceGroupResponse.setCostPrice(costPrice.setScale(2, RoundingMode.UP));
        priceGroupResponse.setSourceCostPrice(sourceCostPrice.setScale(2, RoundingMode.UP));
        //订单总金额
        /*if (pickingId > 0) {
            priceGroupResponse.setTotalPrice(totalPrice.setScale(2, RoundingMode.UP).subtract(taxAndSecondPrice));
            priceGroupResponse.setPayPrice(totalPrice.setScale(2, RoundingMode.UP));
        } else {
            priceGroupResponse.setTotalPrice(totalPrice.setScale(2, RoundingMode.UP));
            priceGroupResponse.setPayPrice(totalPrice.add(taxAndSecondPrice).setScale(2, RoundingMode.UP));
        }*/

        priceGroupResponse.setTotalPrice(totalPrice.setScale(2, RoundingMode.UP));
        priceGroupResponse.setPackagePrice(packagePrice.setScale(2, RoundingMode.UP));
        // TODO DIDIOK PRICE 2
        priceGroupResponse.setPayPrice(totalPrice.add(taxAndSecondPrice).setScale(2, RoundingMode.UP));

        //到货时间（多件取最长）
        Map<Integer, String> map = set.stream().collect(Collectors.toMap(e -> Integer.parseInt(cutString(e, "约", "-")), e -> e, (v1, v2) -> v1));
        Optional<Integer> max = map.keySet().stream().max(Integer::compare);
        String arrivalTime = null;
        if (max.isPresent()) {
            arrivalTime = map.get(max.get());
        }
        priceGroupResponse.setArrivalTime(arrivalTime);
        priceGroupResponse.setAreaType(areaType);
        priceGroupResponse.setPickingId(pickingId);
        return priceGroupResponse;
    }

    /**
     * 获取售价计算方式
     */
    public String getCalculation(Integer markupType, BigDecimal priceChange, Integer priceTailNumber) {
        String str = "";
        if (markupType != null) {
            switch (markupType) {
                case 0:
                    str = "成本价" + priceChange + "%" + PriceTypeEnum.CATE.getMsg();
                    break;
                case 1:
                    str = PriceTypeEnum.FIXED.getMsg();
                    break;
                case 3:
                    str = "成本价" + priceChange + "%" + PriceTypeEnum.MARKUP.getMsg();
                    break;
                case 4:
                    str = "原价" + priceChange.multiply(BigDecimal.TEN) + "%" + PriceTypeEnum.DISCOUNT.getMsg();
                    break;
                default:
                    break;
            }
            str += priceTailNumber == null ? "" : ",售价尾号为" + priceTailNumber;
        }
        return str;
    }


    /**
     * 截取字符串
     *
     * @param str   字符串
     * @param start 开始字符
     * @param end   结束字符
     * @return 截取过后字符串
     */
    private static String cutString(String str, String start, String end) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        String reg = start + "(.*)" + end;
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            str = matcher.group(1);
        }
        return str;
    }

    public BigDecimal checkCouponPrice(List<StoreCartResponse> storeCartResponse, UserAddress userAddress, ChannelMerchant channelMerchant, BigDecimal minPrice) {
        BigDecimal price = BigDecimal.ZERO;
        for (StoreCartResponse cartResponse : storeCartResponse) {
            BigDecimal num = BigDecimal.valueOf(cartResponse.getCartNum());
            price = (price.add(cartResponse.getTruePrice().multiply(num)));
            StoreProductCartProductInfoResponse product = cartResponse.getProductInfo();
            if (product == null) {
                throw new CrmebException("该购物车无产品详情");
            }
            if (product.getIsEurope() == 1 || Objects.equals(channelMerchant.getAppletType(), 0)) {
                continue;
            }
            if (userAddress == null) {
                userAddress = new UserAddress();
            }
            //商品是否包邮
            boolean freeShipping = freeShipping(product.getSuppliersId(), channelMerchant.getId());
            BigDecimal weight = getProductWeightByStoreCar(cartResponse.getProductId(), cartResponse.getProductAttrUnique());

            //一段物流2023.3.23 添加
            CategoryMatch categoryMatch = categoryMatchService.getById(product.getCateId());
            BigDecimal first = getFirstPriceNew(product.getIsEurope(), product.getTempId(), userAddress.getAreaType(), channelMerchant, freeShipping, categoryMatch, product.getSuppliersId());
            //二段物流
            Supplier supplier = supplierService.getById(product.getSuppliersId());
            StoreProduct storeProduct = storeProductDAO.selectById(product.getId());
            BigDecimal second = getSecondPriceNew(storeProduct, userAddress.getAreaType(), channelMerchant,
                    freeShipping, supplier.getId(), weight, supplier.getDirectMailType(), price, cartResponse.getProductAttrUnique(), userAddress);
            //税费
            BigDecimal tax = getTaxPriceNew(storeProduct, userAddress.getAreaType(),
                    cartResponse.getTruePrice().add(first).add(second), channelMerchant, cartResponse.getCostPrice(), freeShipping, false, cartResponse.getIsBtoC());
            price = price.add(tax.multiply(num)).add(second.multiply(num)).add(first.multiply(num));
            if (price.compareTo(minPrice) > -1) {
                return price.subtract(minPrice);
            }
        }
        return price.subtract(minPrice);
    }

    /**
     * 计算服务商商品成本价
     *
     * @param storeProducts 商品
     * @param agentId       服务商id
     */
    public void calcAgentProductPrice(List<StoreProduct> storeProducts, Integer agentId, Integer areaType) {
        RatioVo ratioVo = getAgentSuperiorRatio(agentId);
        ChannelMerchant channelMerchant = new ChannelMerchant();
        List<Integer> cateIds = storeProducts.stream().map(StoreProduct::getCateId).distinct().collect(Collectors.toList());
        Map<Integer, CategoryMatch> categoryMatchMap = categoryMatchService.getByIds(cateIds).stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
        for (StoreProduct product : storeProducts) {
            //商品是否包邮
            boolean freeShipping = freeShipping(product.getSuppliersId(), channelMerchant.getId());
            BigDecimal firstPrice = getFirstPriceNew(product.getIsEurope(), product.getTempId(), areaType, channelMerchant, freeShipping, categoryMatchMap.get(product.getCateId()), product.getSuppliersId());
            BigDecimal cost = calcAgentCost(ratioVo, firstPrice, product.getCost());
            product.setCost(cost);
        }
    }

    /**
     * 计算服务商成本
     *
     * @param ratioVo    加价率
     * @param firstPrice 首段物流
     * @param price      平台成本价
     * @return 服务商成本价
     */
    public BigDecimal calcAgentCost(RatioVo ratioVo, BigDecimal firstPrice, BigDecimal price) {
        BigDecimal firstCostPrice = price.multiply(ratioVo.getPlatRatio()).setScale(2, RoundingMode.HALF_UP).add(firstPrice);
        return firstCostPrice.multiply(ratioVo.getFirstAgentRatio()).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 计算服务商商品规格成本价
     *
     * @param storeProduct 商品
     * @param agentId      服务商id
     */
    public void calcAgentProductAttrValuePrice(List<StoreProductAttrValue> productValues, StoreProduct storeProduct, Integer agentId, Integer areaType, Integer cateId) {
        RatioVo ratioVo = getAgentSuperiorRatio(agentId);
        ChannelMerchant channelMerchant = new ChannelMerchant();
        for (StoreProductAttrValue value : productValues) {
            boolean freeShipping = freeShipping(storeProduct.getSuppliersId(), channelMerchant.getId());
            // 首段物流
            CategoryMatch categoryMatch = categoryMatchService.getById(cateId);
            BigDecimal firstPrice = getFirstPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, categoryMatch, storeProduct.getSuppliersId());
            BigDecimal cost = calcAgentCost(ratioVo, firstPrice, value.getCost());
            value.setCost(cost);
        }
    }

    /**
     * 获取服务商上级加价率
     *
     * @param agentId 服务商 id
     * @return 加价率
     */
    public RatioVo getAgentSuperiorRatio(Integer agentId) {
        Agent agent = agentService.getById(agentId);
        if (null == agent) {
            throw new CrmebException("服务商不存在");
        }
        RatioVo ratioVo = new RatioVo(BigDecimal.ONE, BigDecimal.ONE, null, null, null);
        if (agent.getParentId() > 0) {
            Agent firstAgent = agentService.getById(agent.getParentId());
            if (null == firstAgent) {
                throw new CrmebException("服务商不存在");
            }
            ratioVo.setPlatRatio(BigDecimal.ONE.add(BigDecimal.valueOf(firstAgent.getRatio()).movePointLeft(2)));
            ratioVo.setFirstAgentRatio(BigDecimal.ONE.add(BigDecimal.valueOf(agent.getRatio()).movePointLeft(2)));
        } else {
            ratioVo.setPlatRatio(BigDecimal.ONE.add(BigDecimal.valueOf(agent.getRatio()).movePointLeft(2)));
        }
        return ratioVo;
    }

    public Map<BigDecimal, List<Integer>> calcMemberDiscountPrice(List<StoreProduct> storeProductList, Integer merId, boolean isList) {
        Map<BigDecimal, List<Integer>> map = new HashMap<>();
        if (CollectionUtils.isEmpty(storeProductList)) {
            return map;
        }
        List<Integer> list;
        //查询商家折扣权益
        MerchantMemberBenefits memberBenefits = merchantMemberBenefitsService.getOne(Wrappers.<MerchantMemberBenefits>lambdaQuery().eq(MerchantMemberBenefits::getMerId, merId)
                .eq(MerchantMemberBenefits::getEquityType, 2)
                .eq(MerchantMemberBenefits::getEquityEnableFlag, true)
                .last("LIMIT 1"));
        if (memberBenefits == null || memberBenefits.getDiscountRatio() == null || memberBenefits.getDiscountConditions() == null) {
            return map;
        }
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        Integer condition = memberBenefits.getDiscountConditions();
        //查询当前用户是否为会员
        User user = userService.getInfo();
        UserMemberRecord member = null;
        if (user != null) {
            member = userMemberRecordService.getUserMember(user.getUid());
        }
        //列表展示立减金额
        if (isList) {
            if (getProvincePrice(storeProductList, channelMerchant, map, memberBenefits, condition, member)) {
                return map;
            }
        } else {
            if (member != null) {
                if (getProvincePrice(storeProductList, channelMerchant, map, memberBenefits, condition, member)) {
                    return map;
                }
            } else {
                //商品多少则扣
                if (BooleanUtils.isTrue(channelMerchant.getProductDetailsFlag())) {
                    BigDecimal discount = new BigDecimal(memberBenefits.getDiscountRatio().movePointLeft(1).stripTrailingZeros().toPlainString());
                    if (condition == 1) {
                        for (StoreProduct storeProduct : storeProductList) {
                            //设置折扣
                            storeProduct.setMemberDiscountRatio(discount);
                        }
                    } else if (condition == 2) {
                        //指定商品
                        List<Integer> productIdList = storeProductList.stream().map(StoreProduct::getId).collect(Collectors.toList());
                        List<StoreProductDiscount> discountList = storeProductDiscountService.list(Wrappers.<StoreProductDiscount>lambdaQuery().eq(StoreProductDiscount::getMerId, merId).in(StoreProductDiscount::getProductId, productIdList));
                        if (CollectionUtils.isNotEmpty(discountList)) {
                            list = discountList.stream().map(StoreProductDiscount::getProductId).collect(Collectors.toList());
                            for (StoreProduct storeProduct : storeProductList) {
                                if (list.contains(storeProduct.getId())) {
                                    storeProduct.setMemberDiscountRatio(discount);
                                }
                            }
                        }
                    }
                }
                return map;
            }
        }
        return map;
    }

    private boolean getProvincePrice(List<StoreProduct> storeProductList, ChannelMerchant channelMerchant, Map<BigDecimal, List<Integer>> map, MerchantMemberBenefits memberBenefits, Integer condition, UserMemberRecord member) {
        List<Integer> list;
        //2c
        boolean flag = channelMerchant.getAppletType() == 1;
        if (condition == 1) {
            list = storeProductList.stream().map(StoreProduct::getId).collect(Collectors.toList());
            map.put(memberBenefits.getDiscountRatio(), list);
            for (StoreProduct storeProduct : storeProductList) {
                getProductVipInfo(memberBenefits, member, flag, storeProduct);
            }
            return true;
        } else if (condition == 2) {
            //指定商品
            List<Integer> productIdList = storeProductList.stream().map(StoreProduct::getId).collect(Collectors.toList());
            List<StoreProductDiscount> discountList = storeProductDiscountService.list(Wrappers.<StoreProductDiscount>lambdaQuery().eq(StoreProductDiscount::getMerId, channelMerchant.getId()).in(StoreProductDiscount::getProductId, productIdList));
            if (CollectionUtils.isNotEmpty(discountList)) {
                list = discountList.stream().map(StoreProductDiscount::getProductId).collect(Collectors.toList());
                map.put(memberBenefits.getDiscountRatio(), list);
                for (StoreProduct storeProduct : storeProductList) {
                    if (list.contains(storeProduct.getId())) {
                        getProductVipInfo(memberBenefits, member, flag, storeProduct);
                    }
                }
            }
            return true;
        }
        return false;
    }

    private void getProductVipInfo(MerchantMemberBenefits memberBenefits, UserMemberRecord member, boolean flag, StoreProduct storeProduct) {
        //2b 2c实际售价
        BigDecimal price = flag ? storeProduct.getPrice().add(storeProduct.getTaxAndSecondPrice()) : storeProduct.getPrice();
        BigDecimal discountPrice = price.multiply(BigDecimal.ONE.subtract(memberBenefits.getDiscountRatio().movePointLeft(2))).setScale(2, RoundingMode.DOWN);
        if (discountPrice.compareTo(BigDecimal.ZERO) > 0) {
            storeProduct.setMemberDiscountPrice(discountPrice);
            if (member != null) {
                storeProduct.setVipPrice(price.subtract(discountPrice));
            }
        }
    }

    public void calcValueMemberDiscountPrice(List<StoreProductAttrValue> storeProductAttrValues, BigDecimal discountRatio, Integer appletType) {
        for (StoreProductAttrValue value : storeProductAttrValues) {
            BigDecimal price = appletType == 0 ? value.getPrice() : value.getPrice().add(value.getTaxAndSecondPrice());
            BigDecimal discountPrice = price.multiply(BigDecimal.ONE.subtract(discountRatio.movePointLeft(2))).setScale(2, RoundingMode.DOWN);
            value.setMemberDiscountPrice(discountPrice);
            value.setVipPrice(price.subtract(discountPrice));
        }
    }

    public void calcPickingProductWholesalePrice(List<PickingProductResponse> list, Integer merId, Integer receiptType) {
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
        RatioVo ratioVo = getRatio(channelMerchant);
        List<Integer> cateIds = list.stream().map(PickingProductResponse::getCateId).distinct().collect(Collectors.toList());
        Map<Integer, CategoryMatch> categoryMatchMap = categoryMatchService.getByIds(cateIds).stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
        List<Integer> supplierIds = list.stream().map(PickingProductResponse::getSuppliersId).distinct().collect(Collectors.toList());
        Map<Integer, Supplier> supplierMap = supplierService.listByIds(supplierIds).stream().collect(Collectors.toMap(Supplier::getId, e -> e, (v1, v2) -> v1));
        for (PickingProductResponse product : list) {
            //判断是否自建
            boolean isInside = supplier != null && Objects.equals(supplier.getId(), product.getSuppliersId()) && Objects.equals(product.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(product, productVo);
            //判断商户和供应商商品是否有关联
            ChannelMerchant relatedMerchant = getRelatedMerchant(product.getSuppliersId(), channelMerchant.getId());
            boolean freeShipping = false;
            if (Objects.nonNull(relatedMerchant)) {
                //是否包邮
                if (StringUtils.isNotBlank(relatedMerchant.getFreeIds())) {
                    freeShipping = Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(merId.toString());
                }
                //加价率
                if (StringUtils.isNotBlank(relatedMerchant.getRateIds()) && Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(merId.toString())) {
                    productVo.setPlatRatio(relatedMerchant.getExtraRate());
                }
            }
            if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                BeanUtils.copyProperties(ratioVo, productVo);
            }
            //供应商关联商户
//            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping);
            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, receiptType, false);
//            BigDecimal firstPrice = getFirstPriceNew(product.getIsEurope(), product.getTempId(), receiptType,channelMerchant,freeShipping,product.getCateId(),product.getSuppliersId(),true);
            BigDecimal firstPrice = getFirstPriceNew(product.getIsEurope(), product.getTempId(), receiptType, channelMerchant, freeShipping, categoryMatchMap.get(product.getCateId()), product.getSuppliersId());

            List<StoreProductAttrValue> productAttrValues = storeProductAttrValueService.getListByProductIdAndSkuId(product.getId(), product.getSkuId());
            BigDecimal weight;
            if (CollectionUtils.isEmpty(productAttrValues)) {
                weight = BigDecimal.ZERO;
            } else if (productAttrValues.size() == 1) {
                weight = productAttrValues.get(0).getWeight();
            } else {
                weight = BigDecimal.valueOf(productAttrValues.stream().mapToDouble(e -> e.getWeight().doubleValue()).min().getAsDouble());
            }
            Supplier productSupplier = supplierMap.get(product.getSuppliersId());
            StoreProduct storeProduct = storeProductDAO.selectById(product.getId());
            String sourceSkuId = CollectionUtils.isEmpty(productAttrValues) ? null : productAttrValues.get(0).getSourceSkuId();
            BigDecimal secondPrice = getSecondPriceNew(storeProduct, receiptType, channelMerchant, freeShipping, productSupplier.getId(),
                    weight, productSupplier.getDirectMailType(), merCost, sourceSkuId, null);
            product.setTaxAndSecondPrice(secondPrice.add(firstPrice));
            product.setCost(merCost);
            if (Objects.equals(product.getPriceType(), 0)) {
                product.setWholesalePrice(merCost.multiply(BigDecimal.ONE.add(product.getWholesalePrice().movePointLeft(2))).setScale(2, RoundingMode.UP).add(secondPrice));
            }
        }
    }

    public void calcProductValueWholesalePrice(List<StoreProductAttrValue> productValues, Integer merId, StoreProduct storeProduct, Integer areaType) {
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
        RatioVo ratioVo = getRatio(channelMerchant);
        CategoryMatch categoryMatch = categoryMatchService.getById(storeProduct.getCateId());
        Supplier productSupplier = supplierService.getById(storeProduct.getSuppliersId());
        for (StoreProductAttrValue product : productValues) {
            //判断是否自建
            boolean isInside = supplier != null && Objects.equals(supplier.getId(), storeProduct.getSuppliersId()) && Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode());
            ProductVo productVo = new ProductVo();
            BeanUtils.copyProperties(product, productVo);
            //判断商户和供应商商品是否有关联
            ChannelMerchant relatedMerchant = getRelatedMerchant(storeProduct.getSuppliersId(), channelMerchant.getId());
            boolean freeShipping = false;
            if (Objects.nonNull(relatedMerchant)) {
                //是否包邮
                if (StringUtils.isNotBlank(relatedMerchant.getFreeIds())) {
                    freeShipping = Arrays.asList(relatedMerchant.getFreeIds().split(",")).contains(merId.toString());
                }
                //加价率
                if (StringUtils.isNotBlank(relatedMerchant.getRateIds()) && Arrays.asList(relatedMerchant.getRateIds().split(",")).contains(merId.toString())) {
                    productVo.setPlatRatio(relatedMerchant.getExtraRate());
                }
            }
            if (!isInside && Objects.isNull(productVo.getPlatRatio())) {
                BeanUtils.copyProperties(ratioVo, productVo);
            }
            //供应商关联商户
            BigDecimal merCost = calculateCostPrice(channelMerchant, productVo, isInside, freeShipping, areaType, true);
            BigDecimal firstPrice = getFirstPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, freeShipping, categoryMatch, storeProduct.getSuppliersId());
            BigDecimal secondPrice = getSecondPriceNew(storeProduct, areaType, channelMerchant, freeShipping,
                    productSupplier.getId(), product.getWeight(), productSupplier.getDirectMailType(), merCost, product.getSourceSkuId(), null);
            product.setTaxAndSecondPrice(secondPrice.add(firstPrice));
            product.setCost(merCost);
//            if(product.getPriceType() == 0){
//                product.setWholesalePrice(merCost.multiply(BigDecimal.ONE.add(product.getWholesalePrice().movePointLeft(2))).setScale(2, RoundingMode.UP).add(secondPrice));
//            }
        }


    }

    public void calcSpikePrice(List<StoreProductAttrValue> values, Integer activityId, Integer merId) {
        if (CollectionUtils.isEmpty(values)) {
            return;
        }
        List<StoreProductActivity> productActivityList = storeProductActivityService.list(Wrappers.<StoreProductActivity>lambdaQuery()
                .eq(StoreProductActivity::getActivityId, activityId)
                .eq(StoreProductActivity::getProductId, values.get(0).getProductId()));
        Map<String, StoreProductActivity> activityMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(productActivityList)) {
            activityMap = productActivityList.stream().collect(Collectors.toMap(StoreProductActivity::getSourceSkuId, e -> e));
        }
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        for (StoreProductAttrValue value : values) {
            StoreProductActivity storeProductActivity = activityMap.get(value.getSourceSkuId());
            value.setSpikePrice(Objects.equals(channelMerchant.getAppletType(), 1) ? value.getPrice().add(value.getTaxAndSecondPrice()) : value.getPrice());
            if (storeProductActivity != null && storeProductActivity.getSpikePrice().compareTo(BigDecimal.ZERO) != 0) {
                value.setSpikePrice(storeProductActivity.getSpikePrice());
            }
        }
    }

    public void calcMemberLevelProductPrice(List<StoreProduct> productList, ChannelMerchant channelMerchant, List<ChannelMemberLevel> memberLevelList) {
        if (CollectionUtils.isEmpty(productList) || CollectionUtils.isEmpty(memberLevelList)) {
            return;
        }
        for (StoreProduct product : productList) {
            //等级会员价格计算
            for (ChannelMemberLevel level : memberLevelList) {
                if (level.getLevel() == 1) {
                    continue;
                }
                BigDecimal price = getLevelVipPrice(channelMerchant, level, product.getCost(), product.getPrice(), product.getTaxAndSecondPrice());
                if (level.getLevel() == 2) {
                    product.setV2Price(price);
                } else if (level.getLevel() == 3) {
                    product.setV3Price(price);
                } else {
                    throw new CrmebException("等级会员异常");
                }
            }
        }
    }

    public void calcMemberLevelValuePrice(List<StoreProductAttrValue> storeProductAttrValues, ChannelMerchant channelMerchant, List<ChannelMemberLevel> memberLevelList) {
        if (CollectionUtils.isEmpty(storeProductAttrValues) || CollectionUtils.isEmpty(memberLevelList)) {
            return;
        }
        for (StoreProductAttrValue value : storeProductAttrValues) {
            //计算等级会员价格
            for (ChannelMemberLevel level : memberLevelList) {
                if (level.getLevel() == 1) {
                    continue;
                }
                BigDecimal price = getLevelVipPrice(channelMerchant, level, value.getCost(), value.getPrice(), value.getTaxAndSecondPrice());
                if (level.getLevel() == 2) {
                    value.setV2Price(price);
                } else if (level.getLevel() == 3) {
                    value.setV3Price(price);
                } else {
                    throw new CrmebException("等级会员异常");
                }
            }
        }
    }

    public BigDecimal getLevelVipPrice(ChannelMerchant channelMerchant, ChannelMemberLevel level, BigDecimal cost, BigDecimal price, BigDecimal taxAndSecondPrice) {
        BigDecimal levelPrice;
        switch (level.getPriceLadder()) {
            case 2:
                levelPrice = cost.compareTo(BigDecimal.ZERO) > 0
                        ? cost.multiply(BigDecimal.ONE.add(level.getRatio().movePointLeft(2))).setScale(2, RoundingMode.UP)
                        : price;
                levelPrice = channelMerchant.getAppletType() == 1 ? levelPrice.add(taxAndSecondPrice) : levelPrice;
                break;
            case 3:
                levelPrice = (channelMerchant.getAppletType() == 1 ? price.add(taxAndSecondPrice) : price)
                        .multiply(level.getRatio().movePointLeft(2)).setScale(2, RoundingMode.UP);
                break;
            default:
                throw new CrmebException("等级会员加价方式异常");
        }
        return levelPrice;
    }

    /**
     * 功能描述: 获取购物车中满减金额或满送赠品信息
     *
     * @Param: [storeCartResponse, merId]
     * @Return: java.util.Map<java.lang.String, java.lang.Object>
     * @Author: wangzh
     * @Date: 2023/1/30 14:31
     */
    public Map<String, Object> getDiscountPrice(List<StoreCartResponse> storeCartResponse, Integer merId, Integer areaType) {
        Map<String, Object> response = new HashMap<>();
        // 满送商品信息
        List<StoreProduct> storeProducts = new ArrayList<>();
        // 满减金额
        BigDecimal discountPrice = BigDecimal.ZERO;

        // 查询商家进行中满减送活动
        ChannelDiscountRequest channelDiscountRequest = new ChannelDiscountRequest();
        channelDiscountRequest.setState(1);
        channelDiscountRequest.setStatus(true);
        List<ChannelDiscountDTO> channelDiscountDTOs = channelDiscountService.listEntity(merId, channelDiscountRequest);

        // 活动对应的金额
        Map<Integer, BigDecimal> priceMap = new HashMap<>();
        // 活动对应商品件数
        Map<Integer, Integer> numberMap = new HashMap<>();
        Map<Integer, Boolean> btoCMap = new HashMap<>();
        // 活动与id映射
        Map<Integer, ChannelDiscountDTO> activityMap = new HashMap<>();
        for (StoreCartResponse cartResponse : storeCartResponse) {
            // 购物车商品信息
            StoreProductCartProductInfoResponse productInfo = cartResponse.getProductInfo();
            // 满减送活动信息
            ChannelDiscountDTO channelDiscountDTO = channelDiscountService.checkGoods2ChannelDiscount(merId, productInfo.getId(), channelDiscountDTOs);
            if (null == channelDiscountDTO.getId()) {
                continue;
            }
            Integer id = channelDiscountDTO.getId();
            // 保存活动信息
            if (Objects.isNull(activityMap.get(id))) {
                activityMap.put(id, channelDiscountDTO);
            }
            // 活动总金额计算
            if (Objects.nonNull(priceMap.get(id))) {
                priceMap.put(id, priceMap.get(id).add(cartResponse.getTruePrice().multiply(new BigDecimal(cartResponse.getCartNum()))));
            } else {
                priceMap.put(id, cartResponse.getTruePrice().multiply(new BigDecimal(cartResponse.getCartNum())));
            }
            // 活动商品件数计算
            if (Objects.nonNull(numberMap.get(id))) {
                numberMap.put(id, numberMap.get(id) + cartResponse.getCartNum());
            } else {
                numberMap.put(id, cartResponse.getCartNum());
            }

            btoCMap.put(id, cartResponse.getIsBtoC());
        }
        // 每个活动进行判断
        for (Map.Entry<Integer, ChannelDiscountDTO> entry : activityMap.entrySet()) {
            ChannelDiscountDTO channelDiscountDTO = entry.getValue();
            Integer id = entry.getKey();
            // 当前活动下商品总共购买金额
            BigDecimal price = priceMap.get(id);
            // 当前活动下商品购买件数
            Integer number = numberMap.get(id);
            // 须满足金额 或 件数
            BigDecimal conditionType = channelDiscountDTO.getConditionType();
            // 优惠规则 （阶梯优惠 / 循环优惠）
            Integer discountRule = channelDiscountDTO.getDiscountRule();
            // 优惠方式 （减金额 / 折扣）
            Integer discountType = channelDiscountDTO.getDiscountType();

            Boolean is_btoC = btoCMap.get(id);

            if (is_btoC == null) {
                is_btoC = true;
            }
            switch (channelDiscountDTO.getType()) {
                // 满金额减
                case 1:
                    // 当前金额大于活动规定最低金额
                    if (0 <= price.compareTo(conditionType)) {
                        // 阶梯优惠
                        if (1 == discountRule) {
                            // 减金额
                            if (1 == discountType) {
                                // 满减金额计算
                                discountPrice = discountPrice.add(channelDiscountDTO.getDiscount());
                                //指定折扣
                            } else if (2 == discountType) {
                                discountPrice = discountPrice.add(price.multiply(BigDecimal.ONE.subtract(channelDiscountDTO.getDiscount().movePointLeft(1))));
                            }
                            // 循环优惠
                        } else if (2 == discountRule) {
                            // 减金额
                            if (1 == discountType) {
                                //可优惠几次
                                int i = price.intValue() / conditionType.intValue();
                                // 满减金额计算
                                discountPrice = discountPrice.add(channelDiscountDTO.getDiscount().multiply(new BigDecimal(i)));
                                //指定折扣
                            } else if (2 == discountType) {
                                discountPrice = discountPrice.add(price.multiply(BigDecimal.ONE.subtract(channelDiscountDTO.getDiscount().movePointLeft(1))));
                            }
                        }
                    }
                    break;
                // 满数量送
                case 2:
                    // 当前购买件数大于规定最低件数
                    if (number >= conditionType.intValue()) {
                        // 满件减
                        if (Objects.nonNull(channelDiscountDTO.getDiscount())) {
                            // 阶梯优惠
                            if (1 == discountRule) {
                                // 减金额
                                if (1 == discountType) {
                                    // 满减金额计算
                                    discountPrice = discountPrice.add(channelDiscountDTO.getDiscount());
                                    // 指定折扣
                                } else if (2 == discountType) {
                                    discountPrice = discountPrice.add(price.multiply(BigDecimal.ONE.subtract(channelDiscountDTO.getDiscount().movePointLeft(1))));
                                }
                                // 循环优惠
                            } else if (2 == discountRule) {
                                // 减金额
                                if (1 == discountType) {
                                    //可优惠几次
                                    int i = price.intValue() / conditionType.intValue();
                                    // 满减金额计算
                                    discountPrice = discountPrice.add(channelDiscountDTO.getDiscount().multiply(new BigDecimal(i)));
                                    //指定折扣
                                } else if (2 == discountType) {
                                    discountPrice = discountPrice.add(price.multiply(BigDecimal.ONE.subtract(channelDiscountDTO.getDiscount().movePointLeft(1))));
                                }
                            }
                            // 满件送
                        } else {
                            if (CollectionUtils.isNotEmpty(channelDiscountDTO.getChannelDiscountGoodsList())) {
                                // 赠品id，应该只会有一个
                                List<Integer> productIds = channelDiscountDTO.getChannelDiscountGoodsList().stream().filter(channelDiscountGoods -> channelDiscountGoods.getType() == 2).map(ChannelDiscountGoods::getGoodsId).collect(Collectors.toList());
                                // 赠品信息
                                StoreProduct storeProduct = storeProductService.getById(productIds.get(0));
                                ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
                                //首段物流价格
//                                BigDecimal firstPrice = getFirstPrice(storeProduct.getIsEurope(), storeProduct.getTempId(),channelMerchant,false,storeProduct.getSuppliersName());
                                CategoryMatch categoryMatch = categoryMatchService.getById(storeProduct.getCateId());
                                BigDecimal firstPrice = getFirstPriceNew(storeProduct.getIsEurope(), storeProduct.getTempId(), areaType, channelMerchant, false, categoryMatch, storeProduct.getSuppliersId());
                                //税费
                                BigDecimal truePrice = storeProduct.getPrice();
                                //二段物流
                                List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().eq(StoreProductAttrValue::getProductId, storeProduct.getId()));
                                BigDecimal weight = getProductWeight(attrValues);
                                Supplier supplier = supplierService.getById(storeProduct.getSuppliersId());
                                BigDecimal secondPrice = getSecondPriceNew(storeProduct, areaType, channelMerchant, false, supplier.getId(), weight, supplier.getDirectMailType(), truePrice, null, null);

                                BigDecimal taxPrice = getTaxPriceNew(storeProduct, areaType,
                                        truePrice.add(firstPrice).add(secondPrice), channelMerchant, storeProduct.getCost(), false, false, is_btoC);

                                storeProduct.setTaxAndSecondPrice(taxPrice.add(secondPrice).add(firstPrice));
                                // 阶梯优惠
                                if (1 == discountRule) {
                                    storeProduct.setSales(1);
                                    storeProducts.add(storeProduct);
                                    // 循环优惠
                                } else if (2 == discountRule) {
                                    // 送几件赠品
                                    storeProduct.setSales(number / conditionType.intValue());
                                    storeProducts.add(storeProduct);
                                }
                            }
                        }
                    }
                    break;
            }
        }

        response.put("discountPrice", discountPrice);
        //匹配图片
        productConvertUtil.convertProductImage(storeProducts);
        response.put("giftProductInfos", storeProducts);
        return response;
    }

    /*******************************************************新的运税费计算2023.3.17******************************************************/
    /**
     * 获取首段物流费用
     *
     * @param isEurope        商品来源id
     * @param tempId          发货地id
     * @param areaType        收货地类型
     * @param channelMerchant 商家信息
     * @param freeShipping    包邮包税
     * @param category        分类
     * @param suppliersId     供应商id
     * @return 首段物流费用   2023.3.24修改
     */
    public BigDecimal getFirstPriceNew(Integer isEurope, Integer tempId, Integer areaType, ChannelMerchant channelMerchant,
                                       boolean freeShipping, CategoryMatch category, Integer suppliersId) {
        BigDecimal firstPrice = BigDecimal.ZERO;
        //包邮
        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
            return firstPrice;
        }
        if (Objects.equals(suppliersId, 0)) {
            throw new CrmebException("该商品所属供应商异常");
        }

        //发货地是大陆 保税仓商品 运费为0
        if (StockAreaTempEnum.CN.getTempId().equals(tempId) || StockAreaTempEnum.BA_HK.getTempId().equals(tempId) ||
                StockAreaTempEnum.BA_CH.getTempId().equals(tempId) ||
                StockAreaTempEnum.BA_WZ.getTempId().equals(tempId) || StockAreaTempEnum.BA.getTempId().equals(tempId)
        ) {
            return BigDecimal.ZERO;
        }

        //todo 我爱跨购香港发货不要头程物流
        if (Objects.equals(channelMerchant.getId(), 147)&&Objects.equals(suppliersId,285) && StockAreaTempEnum.HK.getTempId().equals(tempId)){
            return BigDecimal.ZERO;

        }
        // 酒斗士|我爱跨购头程30，暂时先不分发货地了
        if (Objects.equals(channelMerchant.getId(),151)){
            return new BigDecimal("30");
        }

        //发货地是非大陆 进行计算
        //获取到分类的相关运费
        if (Objects.nonNull(category)) {
            //发货地是香港 头层为香港头层
            if (StockAreaTempEnum.HK.getTempId().equals(tempId)) {
                firstPrice = category.getHkFirst();
            } else if (StockAreaTempEnum.EUR.getTempId().equals(tempId) || StockAreaTempEnum.IT.getTempId().equals(tempId)) {  //发货地是意大利 头层为意大利头层
                firstPrice = category.getItFirst();
            }
        }

        return firstPrice;
    }

    /**
     * 获取第二段运费
     *
     * @param storeProduct    发货地id
     * @param areaType        收货地类型
     * @param channelMerchant 商家信息
     * @param freeShipping    包邮包税
     * @param suppliersId     供应商id
     * @return 第二段运费 2023.3.17修改
     */
    public BigDecimal getSecondPriceNew(StoreProduct storeProduct, Integer areaType, ChannelMerchant channelMerchant,
                                        boolean freeShipping, Integer suppliersId, BigDecimal weight, Integer directMailType,
                                        BigDecimal totalPrice, String sourceSkuId, UserAddress userAddress) {
        if (Objects.isNull(storeProduct)) {
            return BigDecimal.ZERO;
        }

        Integer isEurope = storeProduct.getIsEurope();
        Integer tempId = storeProduct.getTempId();
        Integer productId = storeProduct.getId();

        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
            return BigDecimal.ZERO;
        }
        // 我爱跨购香港并且供应商香港环链国际科技发货二段物流特殊处理
        if (Objects.equals(channelMerchant.getId(), 147)&&Objects.equals(suppliersId,285) && StockAreaTempEnum.HK.getTempId().equals(tempId)){
            log.info("我爱跨购香港并且供应商香港环链国际科技发货重量:{}",weight);
            if (weight.compareTo(new BigDecimal("3"))<0){
                return new BigDecimal("27");
            }else {
                return new BigDecimal("80");
            }

        }
        // 我爱跨购保税特殊处理
        if(StockAreaTempEnum.BA.getTempId().equals(tempId)){
            // 我爱跨购单独处理
            if ((Objects.equals(suppliersId,281)||Objects.equals(suppliersId,284)||Objects.equals(suppliersId, 285))&&Objects.equals(channelMerchant.getId(),147)){
                log.error("我爱跨购命中兜底运费weight:{}",weight);
                if (weight.compareTo(new BigDecimal("3"))<0){
                    return new BigDecimal("26.5");
                }else if (weight.compareTo(new BigDecimal("10"))<0){
                    return new BigDecimal("42");
                }else {
                    return new BigDecimal("97");
                }

            }
        }
        if (StockAreaTempEnum.CN.getTempId().equals(tempId)){
            // 我爱跨购单独处理
            if ((Objects.equals(suppliersId,281)||Objects.equals(suppliersId,284)||Objects.equals(suppliersId, 285))&&Objects.equals(channelMerchant.getId(),147)){
                log.error("大陆发货我爱跨购命中兜底运费weight:{}",weight);
                if (weight.compareTo(new BigDecimal("3"))<0){
                    return new BigDecimal("7.5");
                }else {
                    return new BigDecimal("45");
                }

            }
        }

        //自建商品 加发货地是大陆的
        if (Objects.equals(isEurope, ProductTypeEnum.INSIDE.getCode()) || StockAreaTempEnum.CN.getTempId().equals(tempId) || StockAreaTempEnum.BA_HK.getTempId().equals(tempId) ||
                StockAreaTempEnum.BA_CH.getTempId().equals(tempId) ||
                StockAreaTempEnum.BA_WZ.getTempId().equals(tempId) || StockAreaTempEnum.BA.getTempId().equals(tempId)) {

            log.info("isEurope:{} tempId:{} productId:{} sourceSkuId : {} totalPrice:{} ", isEurope, tempId, productId, sourceSkuId, totalPrice);
            BigDecimal freightFee = getFreightFee(storeProduct, totalPrice, sourceSkuId, userAddress);
            return freightFee;

        }

        if (freeDelivery(isEurope, channelMerchant, tempId)) {
            return BigDecimal.ZERO;
        }

        if (Objects.equals(suppliersId, 0)) {
            throw new CrmebException("该商品所属供应商异常");
        }

        //发货地是大陆 保税仓商品 运费为0
//        if (StockAreaTempEnum.CN.getTempId().equals(tempId) || StockAreaTempEnum.BA_HK.getTempId().equals(tempId) ||
//                StockAreaTempEnum.BA_CH.getTempId().equals(tempId) ||
//                StockAreaTempEnum.BA_WZ.getTempId().equals(tempId) || StockAreaTempEnum.BA.getTempId().equals(tempId)
//        )
//        {
//            return BigDecimal.ZERO;
//        }
        BigDecimal secondPostPrice = calculateSecondPostPrice(directMailType, areaType, weight, suppliersId);
        // 我爱跨购单独处理
        if (secondPostPrice.compareTo(BigDecimal.ZERO)<=0
                && (Objects.equals(suppliersId,281)||Objects.equals(suppliersId,284)||Objects.equals(suppliersId, 285))
                &&Objects.equals(channelMerchant.getId(),147)){
            log.error("我爱跨购命中兜底运费weight:{}",weight);

            if (weight.compareTo(new BigDecimal("3"))<0){
                return new BigDecimal("26.5");
            }else if (weight.compareTo(new BigDecimal("10"))<0){
                return new BigDecimal("42");
            }else {
                return new BigDecimal("97");
            }

        }
        return secondPostPrice;

    }

    private BigDecimal calculateSecondPostPrice(Integer directMailType,Integer areaType,BigDecimal weight,Integer suppliersId) {
        if (Objects.nonNull(directMailType)) {
            if (DirectMailTypeEnum.HK.getCode().equals(directMailType)) {//直邮香港
                if (AreaTypeEnum.CN.getType().equals(areaType)) {
                    //算运费
                    BigDecimal freight = calculateFreight(weight);
                    log.info("重量:{} 运费是:{}", weight, freight);
                    return freight;
                } else {
                    //香港预付
                    return Constants.HK_PAYMENT_IN_ADVANCE;
                }
                //直邮中国
            } else {
                if (AreaTypeEnum.HK.getType().equals(areaType)) {
                    //香港预付
                    return Constants.HK_PAYMENT_IN_ADVANCE;
                } else {
                    return BigDecimal.ZERO;
                }
            }
        }
        return BigDecimal.ZERO;

    }

    /**
     * @param areaType        收货地类型id
     * @param price           售价
     * @param channelMerchant 商户
     * @param merCost         平台供货价
     * @return 税费
     */
    public BigDecimal getTaxPriceNew(StoreProduct product,Integer areaType, BigDecimal price,
                                     ChannelMerchant channelMerchant, BigDecimal merCost, boolean freeShipping,
                                     boolean isPicking, boolean isBtoC) {
        Integer isEurope = product.getIsEurope();
        Integer tempId = product.getTempId();
        Integer categoryId = product.getCateId();
        String barCode = product.getBarCode();
        if (freeShipping || freeDelivery(isEurope, channelMerchant, tempId)) {
            return BigDecimal.ZERO;
        }
        //发货地是大陆 税费为0
        if (StockAreaTempEnum.CN.getTempId().equals(tempId)) {
            return BigDecimal.ZERO;
        }
        //平台供货价大于售价,税费按供货价计算
        if (merCost.compareTo(price) > 0) {
            price = merCost;
        }
        //批采订单：运费按照新运费计价，税费=商品供应商的供货价*22%（针对发货地： 非大陆商品  用户收货地为大陆订单或者海外）
        if (isPicking) {  //批采订单
            if (AreaTypeEnum.CN.getType().equals(areaType) || AreaTypeEnum.ABROAD.getType().equals(areaType)) {
                //发货地非大陆 算税
                return price.multiply(new BigDecimal(Constants.DEFAULT_PICKING_POSTAGE_RATE).movePointLeft(2)).setScale(2, RoundingMode.UP);
            }
            return BigDecimal.ZERO;
        }
        // 获取税率
        String taxRate = getTaxRate(categoryId,barCode,product.getFeature("taxRate"));
        //发货地是 保税仓商品 税费为9.1%
        if (StockAreaTempEnum.BA_HK.getTempId().equals(tempId) || StockAreaTempEnum.BA_CH.getTempId().equals(tempId) ||
                StockAreaTempEnum.BA_WZ.getTempId().equals(tempId) || StockAreaTempEnum.BA.getTempId().equals(tempId)) {
            return price.multiply(new BigDecimal(StringUtils.defaultIfBlank(taxRate,Constants.BA_DEFAULT_POSTAGE_RATE)).movePointLeft(2)).setScale(2, RoundingMode.UP);
        }
        if (!AreaTypeEnum.CN.getType().equals(areaType) && !AreaTypeEnum.ABROAD.getType().equals(areaType)){
            //收货地是港澳的免税
            return BigDecimal.ZERO;
        }
        //收货地是大陆或者海外的 计算税
        //商品金额+运费大于5000
        int flag = Constants.TAX_RATE_THRESHOLD.compareTo(price);
        //价格大于5000
        if (flag < 0) {
            return price.multiply(new BigDecimal(StringUtils.defaultIfBlank(taxRate,Constants.DEFAULT_POSTAGE_RATE)).movePointLeft(2)).setScale(2, RoundingMode.UP);
        }
        //2023.4.3 CC模式小于5000 超过26000(系统不判断)
        if (isBtoC) {   //9.1%计算
            return price.multiply(new BigDecimal(StringUtils.defaultIfBlank(taxRate,Constants.BA_DEFAULT_POSTAGE_RATE)).movePointLeft(2)).setScale(2, RoundingMode.UP);
        }
        return price.multiply(new BigDecimal(StringUtils.defaultIfBlank(taxRate,Constants.DEFAULT_POSTAGE_RATE)).movePointLeft(2)).setScale(2, RoundingMode.UP);
    }

    private String getTaxRate(Integer categoryId,String barCode,String productTaxRate) {
        // 根据barcode查询
        String taxRate = getTaxRateByBarCode(barCode);
        if (StringUtils.isNotBlank(taxRate)){
            return taxRate;
        }

        // 酒类根据类目查询
        if (null == categoryId || categoryId == 0){
            return "";
        }
        CategoryMatch categoryMatch = categoryMatchService.getById(categoryId);
        if (null == categoryMatch){
            return "";
        }
        // 二级类目为酒精，并且当前类目没有税率，查询二级类目税率
        if (WINE_SECOND_CATEGORY_ID_LIST.contains(categoryMatch.getPid()) && StringUtils.isBlank(categoryMatch.getFeature("taxTate"))){
            categoryMatch = categoryMatchService.getById(categoryMatch.getPid());
        }
        if (null != categoryMatch && StringUtils.isNotBlank(categoryMatch.getFeature("taxTate"))){
            return categoryMatch.getFeature("taxTate");
        }
        return productTaxRate;

    }

    private String getTaxRateByBarCode(String barCode) {
        if (StringUtils.isBlank(barCode)){
            return "";
        }
        List<CustomsRecord> list = customsRecordService.list(Wrappers.<CustomsRecord>lambdaQuery().eq(CustomsRecord::getBarcode, barCode));
        if (CollectionUtils.isEmpty(list)){
            return "";
        }
        CustomsRecord customsRecord = list.get(0);
        Double declareRate = customsRecord.getDeclareRate();
        if (declareRate!=null && declareRate > 0){
            declareRate = declareRate * 100;
            return String.valueOf(declareRate);
        }
        return "";
    }


    /**
     * 根据商品获取sku下最小重量
     *
     * @param values 商品信息
     * @return 设置的最小重量
     */
    public BigDecimal getProductWeight(List<StoreProductAttrValue> values) {
        if (CollectionUtils.isEmpty(values)) {
            return BigDecimal.ZERO;
        }

        Double weight = values.stream().mapToDouble(e -> e.getWeight().doubleValue()).min().getAsDouble();

        return BigDecimal.valueOf(weight);
    }

    /**
     * 根据购物车的商品信息获取重量
     *
     * @param productId 商品信息
     * @param skuId     商品信息
     * @return 设置的最小重量
     */
    public BigDecimal getProductWeightByStoreCar(Integer productId, String skuId) {

        List<StoreProductAttrValue> productAttrValues = storeProductAttrValueService.getListByProductIdAndSkuId(productId, skuId);

        if (productAttrValues.size() == 1) {
            return productAttrValues.get(0).getWeight();
        } else {
            Double weight = productAttrValues.stream().mapToDouble(e -> e.getWeight().doubleValue()).min().getAsDouble();

            return BigDecimal.valueOf(weight);
        }

    }

    /**
     * 根据重量计算运费
     *
     * @param weight 重量 kg
     * @return 运费
     */
    public BigDecimal calculateFreight(BigDecimal weight) {

        //运费小于首重
        if (Constants.SHIPPING_TEMPLATE_FIRST.compareTo(weight) > 0) {

            return Constants.SHIPPING_TEMPLATE_FIRSTPRICE;

        } else {

            BigDecimal renewal_price = BigDecimal.ZERO;

            BigDecimal[] bigDecimals = weight.subtract(Constants.SHIPPING_TEMPLATE_FIRST).divideAndRemainder(Constants.SHIPPING_TEMPLATE_RENEWAL);

            if (BigDecimal.ZERO.compareTo(bigDecimals[1]) == 0) {  //没有余数

                renewal_price = bigDecimals[0].multiply(Constants.SHIPPING_TEMPLATE_RENEWALPRICE);

            } else {

                renewal_price = bigDecimals[0].add(BigDecimal.ONE).multiply(Constants.SHIPPING_TEMPLATE_RENEWALPRICE);

            }

            return Constants.SHIPPING_TEMPLATE_FIRSTPRICE.add(renewal_price).setScale(2, RoundingMode.UP);
        }

    }

    /**
     * 获取不同币种的汇率
     *
     * @param id
     * @return 运费
     */
    public BigDecimal getMoneyExchange(Integer id) {

        if (id == 0) {
            id = 11;
        }

        MoneyExchange moneyExchange = moneyExchangeService.getById(id);

        if (Objects.isNull(moneyExchange)) {
            return new BigDecimal(DEFAULT_EXCHANGE_RATE_EUR);
        } else {
            BigDecimal money_exchange = new BigDecimal(moneyExchange.getBankConversionPri());
            return money_exchange;

        }

    }

    /**
     * 人民币转不同币种(动态汇率)
     *
     * @param price
     * @return
     */
    public PriceResult rmb2Currency(BigDecimal price, Integer moneyExchangeId) {

        if (price == null) {
            return new PriceResult(BigDecimal.ZERO, BigDecimal.ZERO);
        }

        BigDecimal renewal_price = getMoneyExchange(moneyExchangeId);

//        BigDecimal price1 = price.divide(renewal_price, 2, RoundingMode.HALF_UP);

        return new PriceResult(price.divide(renewal_price, 2, RoundingMode.HALF_UP), renewal_price);

    }

    /**
     * 不同币种转人民币(动态汇率)
     *
     * @param price
     * @return
     */
    public PriceResult currency2Rmb(BigDecimal price, Integer moneyExchangeId) {

        if (price == null) {
            return new PriceResult(BigDecimal.ZERO, BigDecimal.ZERO);
        }

        BigDecimal renewal_price = getMoneyExchange(moneyExchangeId);

        return new PriceResult(price.multiply(renewal_price).setScale(2, RoundingMode.UP), renewal_price);
    }

//    /**
//     * 通过供应商id获取供应商信息
//     * @param supplierId
//     * @return ChannelMerchant
//     */
//    public ChannelMerchant getChannelMerchantBySupplierId(Integer supplierId) {
//
//        ChannelMerchant channelMerchantSupplier = channelMerchantService.getOne(Wrappers.<ChannelMerchant>lambdaQuery()
//                .eq(ChannelMerchant::getChannelType, 3)
//                .eq(ChannelMerchant::getSuppliersIds, "[" + supplierId + "]")
//                .last("LIMIT 1"));
//
//        return channelMerchantSupplier;
//    }

    /**
     * 计算订单运费 2023.5.30
     */
    public BigDecimal getFreightFee(StoreProduct storeProduct, BigDecimal totalPrice, String sourceSkuId, UserAddress userAddress) {
        // 判断是否满额包邮 type=1按件数 2按重量 3按体积

        //先获取运费模板id
//        StoreProduct storeProduct = storeProductDAO.selectById(productId);
        BigDecimal storePostage = BigDecimal.ZERO;
        Integer shippingTempId = 1;   //默认模板id
        BigDecimal weight = BigDecimal.ZERO;
        BigDecimal volume = BigDecimal.ZERO;
        int cityId = 2; //默认城市id
        ShippingTemplates shippingTemplate = new ShippingTemplates();

        if (storeProduct.getIsEurope() == 1) {  //自建商品

            log.info("-----------自建商品 {}-----------", storeProduct.getId());

            if (ObjectUtil.isNotNull(storeProduct.getShippingTempId())) {
                shippingTempId = storeProduct.getShippingTempId();
            }
            StoreProductAttrValue value = new StoreProductAttrValue();
            if (sourceSkuId == null) {
                value = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                        .eq(StoreProductAttrValue::getProductId, storeProduct.getId())
                        .last("LIMIT 1"));
            } else {
                value = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                        .eq(StoreProductAttrValue::getSourceSkuId, sourceSkuId)
                        .eq(StoreProductAttrValue::getProductId, storeProduct.getId())
                        .last("LIMIT 1"));
            }

            if (ObjectUtil.isNotNull(value)) {
                weight = value.getWeight();
                volume = value.getVolume();
            }

        } else  //云仓商品
        //获取商家的商品信息
        {
            log.info("-----------云仓商品 {}-----------", storeProduct.getId());

            StoreProductMer storeProductMer = storeProductMerService.getOne(Wrappers.<StoreProductMer>lambdaQuery()
                    .eq(StoreProductMer::getProductId, storeProduct.getId())
                    .last("limit 1"));

            if (ObjectUtil.isNotNull(storeProductMer) && ObjectUtil.isNotNull(storeProductMer.getShippingTempId())) {
                shippingTempId = storeProductMer.getShippingTempId();
            }

            StoreProductValueMer productValueMer = storeProductValueMerService.getOne(Wrappers.lambdaQuery(StoreProductValueMer.class)
                    .eq(StoreProductValueMer::getProductId, storeProduct.getId())
                    .eq(StoreProductValueMer::getSourceSkuId, sourceSkuId));

            StoreProductAttrValue productValue = storeProductAttrValueService.getOne(Wrappers.lambdaQuery(StoreProductAttrValue.class)
                    .eq(StoreProductAttrValue::getProductId, storeProduct.getId())
                    .eq(StoreProductAttrValue::getSourceSkuId, sourceSkuId));

            if (ObjectUtil.isNotNull(productValueMer)) {
                weight = productValue.getWeight();
                volume = productValueMer.getVolume();
            }
        }

        boolean freeShipping = false;  //是否包邮

        if (ObjectUtil.isNotNull(userAddress)) {   //地址不为空

            // 指定包邮（单品运费模板）> 指定区域配送（单品运费模板）
            if(userAddress.getCityId() != null && userAddress.getCityId() != 0) {
                cityId = userAddress.getCityId();
            }

            shippingTemplate = shippingTemplatesService.getById(shippingTempId);

            log.info("-----------模板shippingTempId {}-----------", shippingTempId);

            if (shippingTemplate.getAppoint()) {// 指定包邮
                // 判断是否在指定包邮区域内
                // 必须满足件数 + 金额 才能包邮
                ShippingTemplatesFree shippingTemplatesFree = shippingTemplatesFreeService.getByTempIdAndCityId(shippingTempId, cityId);
                if (ObjectUtil.isNotNull(shippingTemplatesFree)) { // 在包邮区域内
//
                    switch (shippingTemplate.getType()) {
                        case 1: // 件数

                        case 2: // 重量
                            if (ObjectUtil.isNotNull(weight)) {
                                if (weight.compareTo(new BigDecimal(shippingTemplatesFree.getNumber())) >= 0 || totalPrice.compareTo(shippingTemplatesFree.getPrice()) >= 0) {
                                    log.info("-----------满足重量 或者 金额 = 包邮-----------");
                                    freeShipping = true;
                                }
                            }

                            break;
                        case 3: // 体积
                            if (ObjectUtil.isNotNull(volume)) {
                                if (volume.compareTo(new BigDecimal(shippingTemplatesFree.getNumber())) >= 0 || totalPrice.compareTo(shippingTemplatesFree.getPrice()) >= 0) {
                                    log.info("-----------满足体积 或者 金额 = 包邮-----------");
                                    // 满足体积 + 金额 = 包邮
                                    freeShipping = true;
                                }
                            }
                            break;
                    }

                }
            }

        } else {
            shippingTemplate = shippingTemplatesService.getById(shippingTempId);

        }

        if (freeShipping) {
            log.info("-----------运费包邮了！-----------");
            return BigDecimal.ZERO;
        }
        log.info("-----模板shippingTempId {}-----地址cityId {}------", shippingTempId, cityId);

        // 不满足指定包邮条件，走指定区域配送
        ShippingTemplatesRegion shippingTemplatesRegion = shippingTemplatesRegionService.getByTempIdAndCityId(shippingTempId, cityId);
        if (ObjectUtil.isNull(shippingTemplatesRegion)) {
//            throw new CrmebException("计算运费时，未找到全国运费配置");
            log.info("-----------计算运费时，未找到全国运费配置！-----------");
            return BigDecimal.ZERO;
        }

        // 判断计费方式：件数、重量、体积
        switch (shippingTemplate.getType()) {
            case 1: // 件数
//                // 判断件数是否超过首件
//                Integer num = value.getInt("totalNum");
//                if (num <= shippingTemplatesRegion.getFirst().intValue()) {
//                    storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
//                } else {// 超过首件的需要计算续件
//                    int renewalNum = num - shippingTemplatesRegion.getFirst().intValue();
//                    // 剩余件数/续件 = 需要计算的续件费用的次数
//                    BigDecimal divide = new BigDecimal(renewalNum).divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
//                    BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
//                    storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
//                }
//                break;
            case 2: // 重量

                if (ObjectUtil.isNotNull(weight)) {
                    if (weight.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
                        storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
                    } else {// 超过首件的需要计算续件
                        BigDecimal renewalNum = weight.subtract(shippingTemplatesRegion.getFirst());
                        // 剩余件数/续件 = 需要计算的续件费用的次数
                        BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
                        BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
                        storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
                    }
                }

                break;
            case 3: // 体积
                if (ObjectUtil.isNotNull(volume)) {
                    if (volume.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
                        storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
                    } else {// 超过首件的需要计算续件
                        BigDecimal renewalNum = volume.subtract(shippingTemplatesRegion.getFirst());
                        // 剩余件数/续件 = 需要计算的续件费用的次数
                        BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
                        BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
                        storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
                    }
                }
                break;
        }

        log.info("计算出来的运费：storePostage:{} ------- ", storePostage);
        return storePostage;

    }

}